further implemented bootp protocol

This commit is contained in:
Markus Fröschle
2013-12-24 10:41:43 +00:00
parent 7addadeb70
commit c1ff9a7181
8 changed files with 427 additions and 524 deletions

View File

@@ -8,12 +8,28 @@
#ifndef _BOOTP_H_ #ifndef _BOOTP_H_
#define _BOOTP_H_ #define _BOOTP_H_
/********************************************************************/ #define BOOTP_SERVER_PORT 67
#define BOOTP_CLIENT_PORT 68
/* protocol header information */
#define BOOTP_HDR_OFFSET (ETH_HDR_LEN + IP_HDR_SIZE + UDP_HDR_SIZE)
/* timeout in seconds */
#define BOOTP_TIMEOUT 2
/* BOOTP connection status */
struct bootp_connection
{
bool open; /* connection established flag */
NIF *nif; /* pointer to network interface */
IP_ADDR server_ip; /* server IP address */
};
/* /*
* This data definition is defined for Ethernet only! * This data definition is defined for Ethernet only!
*/ */
typedef struct struct bootp_packet
{ {
uint8_t type; /* bootp operation type */ uint8_t type; /* bootp operation type */
uint8_t htype; /* hardware type */ uint8_t htype; /* hardware type */
@@ -29,9 +45,9 @@ typedef struct
uint8_t sname[64]; /* server name */ uint8_t sname[64]; /* server name */
uint8_t file[128]; /* name of bootfile */ uint8_t file[128]; /* name of bootfile */
uint8_t vend[64]; /* vendor specific (see below) */ uint8_t vend[64]; /* vendor specific (see below) */
} bootp_frame_hdr; };
#define BOOTP_HDR_LEN sizeof(bootp_frame_hdr) #define BOOTP_PACKET_LEN (BOOTP_HDR_OFFSET + sizeof(struct bootp_packet))
/* possible values for type field */ /* possible values for type field */
#define BOOTP_TYPE_BOOTREQUEST 1 #define BOOTP_TYPE_BOOTREQUEST 1
@@ -46,11 +62,6 @@ typedef struct
/* values for flags - only broadcast flag in use */ /* values for flags - only broadcast flag in use */
#define BOOTP_FLAGS_BROADCAST 1 #define BOOTP_FLAGS_BROADCAST 1
#define BOOTP_TIMEOUT (1) /* Timeout in seconds */
/* Protocol Header information */
#define BOOTP_HDR_OFFSET ETH_HDR_LEN
extern void bootp_request(NIF *, uint8_t *); extern void bootp_request(NIF *, uint8_t *);
extern void bootp_handler(NIF *, NBUF *); extern void bootp_handler(NIF *, NBUF *);
//extern void bootp_init(BOOTP_INFO *); //extern void bootp_init(BOOTP_INFO *);

View File

@@ -47,39 +47,23 @@
*/ */
typedef struct typedef struct
{ {
QNODE node; QNODE node;
uint8_t *data; uint8_t *data;
uint16_t offset; uint16_t offset;
uint16_t length; uint16_t length;
} NBUF; } NBUF;
/* /*
* Functions to manipulate the network buffers. * Functions to manipulate the network buffers.
*/ */
int extern int nbuf_init(void);
nbuf_init(void); extern void nbuf_flush(void);
extern NBUF *nbuf_alloc (void);
extern void nbuf_free(NBUF *);
extern NBUF *nbuf_remove(int);
extern void nbuf_add(int, NBUF *);
extern void nbuf_reset(void);
extern void nbuf_debug_dump(void);
void
nbuf_flush(void);
NBUF *
nbuf_alloc (void);
void
nbuf_free(NBUF *);
NBUF *
nbuf_remove(int);
void
nbuf_add(int, NBUF *);
void
nbuf_reset(void);
void
nbuf_debug_dump(void);
/********************************************************************/
#endif /* _NBUF_H_ */ #endif /* _NBUF_H_ */

View File

@@ -1,6 +1,6 @@
/* /*
* File: net.h * File: net.h
* Purpose: Network definitions and prototypes for dBUG. * Purpose: Network definitions and prototypes for BaS.
* *
* Notes: * Notes:
*/ */
@@ -24,7 +24,7 @@
/********************************************************************/ /********************************************************************/
int net_init(void); extern int net_init(void);
/********************************************************************/ /********************************************************************/

View File

@@ -1,9 +1,8 @@
/* /*
* File: net_timer.h * File: net_timer.h
* Purpose: Provide a timer use by the dBUG network as a timeout * Purpose: Provide a timer use by the BaS network as a timeout
* indicator * indicator
* *
* Notes:
*/ */
#ifndef _TIMER_H_ #ifndef _TIMER_H_

View File

@@ -8,8 +8,6 @@
#ifndef _TFTP_H_ #ifndef _TFTP_H_
#define _TFTP_H_ #define _TFTP_H_
/********************************************************************/
#define TFTP_RRQ (1) #define TFTP_RRQ (1)
#define TFTP_WRQ (2) #define TFTP_WRQ (2)
#define TFTP_DATA (3) #define TFTP_DATA (3)

View File

@@ -9,9 +9,14 @@
#include "bootp.h" #include "bootp.h"
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include "bas_printf.h"
#define TIMER_NETWORK 0 #define TIMER_NETWORK 0
static struct bootp_connection connection;
#define XID 0x1234 /* this is arbitrary */
#define MAX_TRIES 5 /* since UDP can fail */
void bootp_request(NIF *nif, uint8_t *pa) void bootp_request(NIF *nif, uint8_t *pa)
{ {
/* /*
@@ -19,172 +24,75 @@ void bootp_request(NIF *nif, uint8_t *pa)
* address "pa" * address "pa"
*/ */
uint8_t *addr; uint8_t *addr;
NBUF *pNbuf; IP_ADDR broadcast = {255, 255, 255, 255};
bootp_frame_hdr *bootpframe; NBUF *nbuf;
struct bootp_packet *p;
int i, result; int i, result;
pNbuf = nbuf_alloc(); nbuf = nbuf_alloc();
if (pNbuf == NULL) if (nbuf == NULL)
{ {
#if defined(DEBUG_PRINT) xprintf("%s: couldn't allocate Tx buffer\r\n", __FUNCTION__);
xprintf("%s: arp_request couldn't allocate Tx buffer\r\n", __FUNCTION__); return;
#endif
return;
} }
bootpframe = (bootp_frame_hdr *) &pNbuf->data[BOOTP_HDR_OFFSET]; p = (struct bootp_packet *) &nbuf->data[BOOTP_HDR_OFFSET];
/* Build the BOOTP request packet */ /* Build the BOOTP request packet */
bootpframe->type = BOOTP_TYPE_BOOTREQUEST; p->type = BOOTP_TYPE_BOOTREQUEST;
bootpframe->htype = BOOTP_HTYPE_ETHERNET; p->htype = BOOTP_HTYPE_ETHERNET;
bootpframe->hlen = BOOTP_HLEN_ETHERNET; p->hlen = BOOTP_HLEN_ETHERNET;
bootpframe->hops = 0; p->hops = 0;
bootpframe->xid = 0x1234; p->xid = XID;
bootpframe->secs = 1; p->secs = 1;
bootpframe->flags = BOOTP_FLAGS_BROADCAST; p->flags = BOOTP_FLAGS_BROADCAST;
bootpframe->cl_addr = 0x0; p->cl_addr = 0x0;
bootpframe->yi_addr = 0x0; p->yi_addr = 0x0;
bootpframe->gi_addr = 0x0; p->gi_addr = 0x0;
addr = &nif->hwa[0]; addr = &nif->hwa[0];
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
bootpframe->ch_addr[i] = addr[i]; p->ch_addr[i] = addr[i];
pNbuf->length = BOOTP_HDR_LEN; nbuf->length = BOOTP_PACKET_LEN;
/* Send the BOOTP request */ for (i = 0; i < MAX_TRIES; i++)
result = nif->send(nif, nif->broadcast, nif->hwa, ETH_FRM_IP, pNbuf); {
/* Send the BOOTP request */
result = udp_send(connection.nif, broadcast, BOOTP_CLIENT_PORT,
BOOTP_SERVER_PORT, nbuf);
if (result == true)
break;
}
if (result == 0) if (result == 0)
nbuf_free(pNbuf); nbuf_free(nbuf);
} }
void bootp_handler(NIF *nif, NBUF *pNbuf) void bootp_handler(NIF *nif, NBUF *nbuf)
{ {
/* /*
* ARP protocol handler * BOOTP protocol handler
*/ */
uint8_t *addr; uint8_t *addr;
bootp_frame_hdr *rx_bootpframe, *tx_bootpframe; struct bootp_packet *rx_p;
udp_frame_hdr *udpframe;
rx_bootpframe = (bootp_frame_hdr *) &pNbuf->data[pNbuf->offset]; rx_p = (struct bootp_packet *) &nbuf->data[nbuf->offset];
udpframe = (udp_frame_hdr *) &nbuf->data[nbuf->offset - UDP_HDR_SIZE];
#ifdef _NOT_USED_ /* check packet if it is valid and if it is really intended for us */
/*
* Check for an appropriate ARP packet if (rx_p->type == BOOTP_TYPE_BOOTREPLY && rx_p->xid == XID)
*/
if ((pNbuf->length < ARP_HDR_LEN) ||
(rx_arpframe->ar_hrd != ETHERNET) ||
(rx_arpframe->ar_hln != 6) ||
(rx_arpframe->ar_pro != ETH_FRM_IP) ||
(rx_arpframe->ar_pln != 4))
{ {
nbuf_free(pNbuf); /* seems to be valid */
return;
}
/*
* Check to see if it was addressed to me - if it was, keep this
* ARP entry in the table permanently; if not, mark it so that it
* can be displaced later if necessary
*/
addr = ip_get_myip(nif_get_protocol_info(nif,ETH_FRM_IP));
if ((rx_arpframe->ar_tpa[0] == addr[0]) &&
(rx_arpframe->ar_tpa[1] == addr[1]) &&
(rx_arpframe->ar_tpa[2] == addr[2]) &&
(rx_arpframe->ar_tpa[3] == addr[3]) )
{
longevity = ARP_ENTRY_PERM;
} }
else else
longevity = ARP_ENTRY_TEMP;
/*
* Add ARP info into the table
*/
arp_merge(arptab,
rx_arpframe->ar_pro,
rx_arpframe->ar_hln,
&rx_arpframe->ar_sha[0],
rx_arpframe->ar_pln,
&rx_arpframe->ar_spa[0],
longevity
);
switch (rx_arpframe->opcode)
{ {
case ARP_REQUEST: /* not valid */
/* return;
* Check to see if request is directed to me }
*/
if ((rx_arpframe->ar_tpa[0] == addr[0]) &&
(rx_arpframe->ar_tpa[1] == addr[1]) &&
(rx_arpframe->ar_tpa[2] == addr[2]) &&
(rx_arpframe->ar_tpa[3] == addr[3]) )
{
/*
* Reuse the current network buffer to assemble an ARP reply
*/
tx_arpframe = (arp_frame_hdr *)&pNbuf->data[ARP_HDR_OFFSET];
/*
* Build new ARP frame from the received data
*/
tx_arpframe->ar_hrd = ETHERNET;
tx_arpframe->ar_pro = ETH_FRM_IP;
tx_arpframe->ar_hln = 6;
tx_arpframe->ar_pln = 4;
tx_arpframe->opcode = ARP_REPLY;
tx_arpframe->ar_tha[0] = rx_arpframe->ar_sha[0];
tx_arpframe->ar_tha[1] = rx_arpframe->ar_sha[1];
tx_arpframe->ar_tha[2] = rx_arpframe->ar_sha[2];
tx_arpframe->ar_tha[3] = rx_arpframe->ar_sha[3];
tx_arpframe->ar_tha[4] = rx_arpframe->ar_sha[4];
tx_arpframe->ar_tha[5] = rx_arpframe->ar_sha[5];
tx_arpframe->ar_tpa[0] = rx_arpframe->ar_spa[0];
tx_arpframe->ar_tpa[1] = rx_arpframe->ar_spa[1];
tx_arpframe->ar_tpa[2] = rx_arpframe->ar_spa[2];
tx_arpframe->ar_tpa[3] = rx_arpframe->ar_spa[3];
/*
* Now copy in the new information
*/
addr = &nif->hwa[0];
tx_arpframe->ar_sha[0] = addr[0];
tx_arpframe->ar_sha[1] = addr[1];
tx_arpframe->ar_sha[2] = addr[2];
tx_arpframe->ar_sha[3] = addr[3];
tx_arpframe->ar_sha[4] = addr[4];
tx_arpframe->ar_sha[5] = addr[5];
addr = ip_get_myip(nif_get_protocol_info(nif,ETH_FRM_IP));
tx_arpframe->ar_spa[0] = addr[0];
tx_arpframe->ar_spa[1] = addr[1];
tx_arpframe->ar_spa[2] = addr[2];
tx_arpframe->ar_spa[3] = addr[3];
/*
* Save the length of my packet in the buffer structure
*/
pNbuf->length = ARP_HDR_LEN;
nif->send(nif,
&tx_arpframe->ar_tha[0],
&tx_arpframe->ar_sha[0],
ETH_FRM_ARP,
pNbuf);
}
else
nbuf_free(pNbuf);
break;
case ARP_REPLY:
/*
* The ARP Reply case is already taken care of
*/
default:
nbuf_free(pNbuf);
break;
}
#endif /* _NOT_USED_ */
return; return;
} }

View File

@@ -1,6 +1,6 @@
/* /*
* File: net_timer.c * File: net_timer.c
* Purpose: Provide a timer use by the dBUG network as a timeout * Purpose: Provide a timer use by the BaS network as a timeout
* indicator * indicator
* *
* Notes: * Notes:
@@ -19,158 +19,161 @@
#error unknown machine! #error unknown machine!
#endif #endif
static NET_TIMER net_timer[4] = {{0, 0, 0, 0, 0, 0, 0}, static NET_TIMER net_timer[4] =
{0, 0, 0, 0, 0, 0, 0}, {
{0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0}}; {0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0}
};
int timer_default_isr(void *not_used, NET_TIMER *t) int timer_default_isr(void *not_used, NET_TIMER *t)
{ {
(void) not_used; (void) not_used;
/* /*
* Clear the pending event * Clear the pending event
*/ */
MCF_GPT_GMS(t->ch) = 0; MCF_GPT_GMS(t->ch) = 0;
/* /*
* Clear the reference - the desired seconds have expired * Clear the reference - the desired seconds have expired
*/ */
t->reference = 0; t->reference = 0;
return 1; return 1;
} }
void timer_irq_enable(uint8_t ch) void timer_irq_enable(uint8_t ch)
{ {
/* /*
* Setup the appropriate ICR * Setup the appropriate ICR
*/ */
MCF_INTC_ICR(TIMER_VECTOR(ch) - 64) = MCF_INTC_ICR(TIMER_VECTOR(ch) - 64) =
(uint8_t)(0 (uint8_t)(0
| MCF_INTC_ICR_IP(net_timer[ch].pri) | MCF_INTC_ICR_IP(net_timer[ch].pri)
| MCF_INTC_ICR_IL(net_timer[ch].lvl)); | MCF_INTC_ICR_IL(net_timer[ch].lvl));
/* /*
* Unmask the FEC interrupt in the interrupt controller * Unmask the FEC interrupt in the interrupt controller
*/ */
if (ch == 3) if (ch == 3)
MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK59; MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK59;
else if (ch == 2) else if (ch == 2)
MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK60; MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK60;
else if (ch == 1) else if (ch == 1)
MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK61; MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK61;
else else
MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK62; MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK62;
} }
bool timer_set_secs(uint8_t ch, uint32_t secs) bool timer_set_secs(uint8_t ch, uint32_t secs)
{ {
uint16_t timeout; uint16_t timeout;
/* /*
* Reset the timer * Reset the timer
*/ */
MCF_GPT_GMS(ch) = 0; MCF_GPT_GMS(ch) = 0;
/* /*
* Get the timeout in seconds * Get the timeout in seconds
*/ */
timeout = (uint16_t)(secs * net_timer[ch].cnt); timeout = (uint16_t)(secs * net_timer[ch].cnt);
/* /*
* Set the reference indicating that we have not yet reached the * Set the reference indicating that we have not yet reached the
* desired timeout * desired timeout
*/ */
net_timer[ch].reference = 1; net_timer[ch].reference = 1;
/* /*
* Enable timer interrupt to the processor * Enable timer interrupt to the processor
*/ */
timer_irq_enable(ch); timer_irq_enable(ch);
/* /*
* Enable the timer using the pre-calculated values * Enable the timer using the pre-calculated values
*/ */
MCF_GPT_GCIR(ch) = (0 MCF_GPT_GCIR(ch) = (0
| MCF_GPT_GCIR_CNT(timeout) | MCF_GPT_GCIR_CNT(timeout)
| MCF_GPT_GCIR_PRE(net_timer[ch].pre) | MCF_GPT_GCIR_PRE(net_timer[ch].pre)
); );
MCF_GPT_GMS(ch) = net_timer[ch].gms; MCF_GPT_GMS(ch) = net_timer[ch].gms;
return true; return true;
} }
uint32_t timer_get_reference(uint8_t ch) uint32_t timer_get_reference(uint8_t ch)
{ {
return (uint32_t) net_timer[ch].reference; return (uint32_t) net_timer[ch].reference;
} }
bool timer_init(uint8_t ch, uint8_t lvl, uint8_t pri) bool timer_init(uint8_t ch, uint8_t lvl, uint8_t pri)
{ {
/* /*
* Initialize the timer to expire after one second * Initialize the timer to expire after one second
* *
* This routine should only be called by the project (board) specific * This routine should only be called by the project (board) specific
* initialization code. * initialization code.
*/ */
if (!((ch <= 3) && (lvl <= 7) && (lvl >= 1) && (pri <= 7))) if (!((ch <= 3) && (lvl <= 7) && (lvl >= 1) && (pri <= 7)))
return false; return false;
/* /*
* Reset the timer * Reset the timer
*/ */
MCF_GPT_GMS(ch) = 0; MCF_GPT_GMS(ch) = 0;
/* /*
* Save off the channel, and interrupt lvl/pri information * Save off the channel, and interrupt lvl/pri information
*/ */
net_timer[ch].ch = ch; net_timer[ch].ch = ch;
net_timer[ch].lvl = lvl; net_timer[ch].lvl = lvl;
net_timer[ch].pri = pri; net_timer[ch].pri = pri;
/* /*
* Register the timer interrupt handler * Register the timer interrupt handler
*/ */
if (!isr_register_handler(ISR_DBUG_ISR, if (!isr_register_handler(ISR_DBUG_ISR,
TIMER_VECTOR(ch), TIMER_VECTOR(ch),
(int (*)(void *,void *)) timer_default_isr, (int (*)(void *,void *)) timer_default_isr,
NULL, NULL,
(void *) &net_timer[ch]) (void *) &net_timer[ch])
) )
{ {
return false; return false;
} }
/* /*
* Calculate the require CNT value to get a 1 second timeout * Calculate the require CNT value to get a 1 second timeout
* *
* 1 sec = CNT * Clk Period * PRE * 1 sec = CNT * Clk Period * PRE
* CNT = 1 sec / (Clk Period * PRE) * CNT = 1 sec / (Clk Period * PRE)
* CNT = Clk Freq / PRE * CNT = Clk Freq / PRE
* *
* The system clock frequency is defined as SYSTEM_CLOCK and * The system clock frequency is defined as SYSTEM_CLOCK and
* is given in MHz. We need to multiple it by 1000000 to get the * is given in MHz. We need to multiple it by 1000000 to get the
* true value. If we assume PRE to be the maximum of 0xFFFF, * true value. If we assume PRE to be the maximum of 0xFFFF,
* then the CNT value needed to achieve a 1 second timeout is * then the CNT value needed to achieve a 1 second timeout is
* given by: * given by:
* *
* CNT = SYSTEM_CLOCK * (1000000/0xFFFF) * CNT = SYSTEM_CLOCK * (1000000/0xFFFF)
*/ */
net_timer[ch].pre = 0xFFFF; net_timer[ch].pre = 0xFFFF;
net_timer[ch].cnt = (uint16_t) (SYSCLK * (1000000 / 0xFFFF)); net_timer[ch].cnt = (uint16_t) (SYSCLK * (1000000 / 0xFFFF));
/* /*
* Save off the appropriate mode select register value * Save off the appropriate mode select register value
*/ */
net_timer[ch].gms = (0 net_timer[ch].gms = (0
| MCF_GPT_GMS_TMS_GPIO | MCF_GPT_GMS_TMS_GPIO
| MCF_GPT_GMS_IEN | MCF_GPT_GMS_IEN
| MCF_GPT_GMS_SC | MCF_GPT_GMS_SC
| MCF_GPT_GMS_CE | MCF_GPT_GMS_CE
); );
return true; return true;
} }

View File

@@ -52,7 +52,7 @@ int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority,
{ {
xprintf("%s: interrupt source %d not defined\r\n", __FUNCTION__, source); xprintf("%s: interrupt source %d not defined\r\n", __FUNCTION__, source);
return -1; return -1;
} }
lp = MCF_INTC_ICR_IL(level) | MCF_INTC_ICR_IP(priority); lp = MCF_INTC_ICR_IL(level) | MCF_INTC_ICR_IP(priority);
@@ -88,11 +88,11 @@ int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority,
typedef struct typedef struct
{ {
int vector; int vector;
int type; int type;
int (*handler)(void *, void *); int (*handler)(void *, void *);
void *hdev; void *hdev;
void *harg; void *harg;
} ISRENTRY; } ISRENTRY;
ISRENTRY isrtab[UIF_MAX_ISR_ENTRY]; ISRENTRY isrtab[UIF_MAX_ISR_ENTRY];
@@ -100,126 +100,126 @@ ISRENTRY isrtab[UIF_MAX_ISR_ENTRY];
void isr_init(void) void isr_init(void)
{ {
int index; int index;
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++) for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
{ {
isrtab[index].vector = 0; isrtab[index].vector = 0;
isrtab[index].type = 0; isrtab[index].type = 0;
isrtab[index].handler = 0; isrtab[index].handler = 0;
isrtab[index].hdev = 0; isrtab[index].hdev = 0;
isrtab[index].harg = 0; isrtab[index].harg = 0;
} }
} }
int isr_register_handler ( int isr_register_handler (
int type, int vector, int type, int vector,
int (*handler)(void *, void *), void *hdev, void *harg) int (*handler)(void *, void *), void *hdev, void *harg)
{ {
/* /*
* This function places an interrupt handler in the ISR table, * This function places an interrupt handler in the ISR table,
* thereby registering it so that the low-level handler may call it. * thereby registering it so that the low-level handler may call it.
* *
* The two parameters are intended for the first arg to be a * The two parameters are intended for the first arg to be a
* pointer to the device itself, and the second a pointer to a data * pointer to the device itself, and the second a pointer to a data
* structure used by the device driver for that particular device. * structure used by the device driver for that particular device.
*/ */
int index; int index;
if ((vector == 0) || if ((vector == 0) ||
((type != ISR_DBUG_ISR) && (type != ISR_USER_ISR)) || ((type != ISR_DBUG_ISR) && (type != ISR_USER_ISR)) ||
(handler == NULL)) (handler == NULL))
{ {
return true; return true;
} }
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++) for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
{ {
if ((isrtab[index].vector == vector) && if ((isrtab[index].vector == vector) &&
(isrtab[index].type == type)) (isrtab[index].type == type))
{ {
/* only one entry of each type per vector */ /* only one entry of each type per vector */
return 0; return 0;
} }
if (isrtab[index].vector == 0) if (isrtab[index].vector == 0)
{ {
isrtab[index].vector = vector; isrtab[index].vector = vector;
isrtab[index].type = type; isrtab[index].type = type;
isrtab[index].handler = handler; isrtab[index].handler = handler;
isrtab[index].hdev = hdev; isrtab[index].hdev = hdev;
isrtab[index].harg = harg; isrtab[index].harg = harg;
return 1; return 1;
} }
} }
return false; /* no available slots */ return false; /* no available slots */
} }
void isr_remove_handler(int type, int (*handler)(void *, void *)) void isr_remove_handler(int type, int (*handler)(void *, void *))
{ {
/* /*
* This routine removes from the ISR table all * This routine removes from the ISR table all
* entries that matches 'type' and 'handler'. * entries that matches 'type' and 'handler'.
*/ */
int index; int index;
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++) for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
{ {
if ((isrtab[index].handler == handler) && if ((isrtab[index].handler == handler) &&
(isrtab[index].type == type)) (isrtab[index].type == type))
{ {
isrtab[index].vector = 0; isrtab[index].vector = 0;
isrtab[index].type = 0; isrtab[index].type = 0;
isrtab[index].handler = 0; isrtab[index].handler = 0;
isrtab[index].hdev = 0; isrtab[index].hdev = 0;
isrtab[index].harg = 0; isrtab[index].harg = 0;
} }
} }
} }
bool isr_execute_handler(int vector) bool isr_execute_handler(int vector)
{ {
/* /*
* This routine searches the ISR table for an entry that matches * This routine searches the ISR table for an entry that matches
* 'vector'. If one is found, then 'handler' is executed. * 'vector'. If one is found, then 'handler' is executed.
*/ */
int index; int index;
bool retval = false; bool retval = false;
/* /*
* First locate a dBUG Interrupt Service Routine handler. * First locate a BaS Interrupt Service Routine handler.
*/ */
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++) for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
{ {
if ((isrtab[index].vector == vector) && if ((isrtab[index].vector == vector) &&
(isrtab[index].type == ISR_DBUG_ISR)) (isrtab[index].type == ISR_DBUG_ISR))
{ {
if (isrtab[index].handler(isrtab[index].hdev,isrtab[index].harg)) if (isrtab[index].handler(isrtab[index].hdev,isrtab[index].harg))
{ {
retval = true; retval = true;
break; break;
} }
} }
} }
/* /*
* Try to locate a user-registered Interrupt Service Routine handler. * Try to locate a user-registered Interrupt Service Routine handler.
*/ */
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++) for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
{ {
if ((isrtab[index].vector == vector) && if ((isrtab[index].vector == vector) &&
(isrtab[index].type == ISR_USER_ISR)) (isrtab[index].type == ISR_USER_ISR))
{ {
if (isrtab[index].handler(isrtab[index].hdev,isrtab[index].harg)) if (isrtab[index].handler(isrtab[index].hdev,isrtab[index].harg))
{ {
retval = true; retval = true;
break; break;
} }
} }
} }
return retval; return retval;
} }