|
|
GNU Mach 1.0
/*
* Mach Operating System
* Copyright (c) 1992 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or [email protected]
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
#include <atm.h>
#if NATM > 0
#include <vm/vm_kern.h>
#include <machine/machspl.h> /* spl definitions */
#include <kern/time_out.h> /* ? maybe */
#include <device/errno.h>
#include <device/io_req.h>
#include <device/net_status.h>
#include <chips/busses.h>
#include <chips/atmreg.h>
#include <kern/eventcount.h>
#include <mips/mips_cpu.h>
struct bus_device *atm_info[NATM];
int atm_probe();
static void atm_attach();
struct bus_driver atm_driver =
{ atm_probe, 0, atm_attach, 0, /* csr */ 0, "atm", atm_info,
"", 0, /* flags */ 0 }; /* ENABLED BUS INTR? */
/* XX "", 0, BUS_INTR_DISABLED}; */
typedef struct atm_softc {
struct atm_device *atm_dev;
struct evc atm_eventcounter;
mapped_atm_info_t atm_mapped_info;
} atm_softc_t;
natural_t atm_nintrs = 0;
atm_softc_t atm_softc[NATM];
atm_probe(reg, ui)
vm_offset_t reg;
register struct bus_device *ui;
{
register atm_softc_t *atm;
mapped_atm_info_t info; /* info struct to hand to users */
vm_offset_t addr;
int unit = ui->unit;
if (check_memory(reg, 0)) {
return 0;
}
atm_info[unit] = ui;
atm = &atm_softc[unit];
atm->atm_dev = (struct atm_device *) reg; /* k1 address */
evc_init(&atm->atm_eventcounter);
printf("evc_init of atm: event counter id is %d\n", atm->atm_eventcounter.ev_id);
/* initialize the interface to deliver. No interrupts by default */
atm->atm_dev->sreg = 0;
atm->atm_dev->creg = (CR_RX_RESET | CR_TX_RESET);
atm->atm_dev->creg = 0;
atm->atm_dev->creg_set = (CR_RX_ENABLE | CR_TX_ENABLE);
#ifdef notdef
atm->atm_dev->rxthresh = 0;
atm->atm_dev->rxtimerv = 0;
atm->atm_dev->creg_s = RX_EOM_INTR; /* enable interrupt on end of message */
#endif
/*
* Grab a page to be mapped later to users
*/
(void) kmem_alloc_wired(kernel_map, &addr, PAGE_SIZE); /* kseg2 */
bzero(addr, PAGE_SIZE);
addr = pmap_extract(pmap_kernel(), addr); /* phys */
info = (mapped_atm_info_t) PHYS_TO_K0SEG(addr);
atm->atm_mapped_info = info;
/*
* Set some permanent info
*/
info->hello_world = 0xdeadbeef;
info->interrupt_count = 0;
info->wait_event = atm->atm_eventcounter.ev_id;
info->saved_status_reg = 0;
return 1;
}
static void
atm_attach(ui)
register struct bus_device *ui;
{
}
int atm_disable_interrupts_after_each = 1;
#define ATM_INTERRUPTS (RX_COUNT_INTR | RX_EOM_INTR | RX_TIME_INTR)
atm_intr(unit, spllevel)
int unit;
int spllevel;
{
register struct atm_softc *atm = &atm_softc[unit];
struct atm_device *atm_dev = atm->atm_dev;
unsigned int intr;
if (atm_dev == 0) {
printf("atm: stray interrupt\n");
return;
}
/* Acknowledge interrupt request */
intr = ATM_READ_REG(atm_dev->sreg);
atm_dev->sreg = ~(intr & ATM_INTERRUPTS);
/* clear the reason for the interrupt */
if (atm_disable_interrupts_after_each)
atm_dev->creg &= ~intr;
splx(spllevel); /* drop priority now */
atm_intr_occurred();
/* Pass status info up to user */
if (atm->atm_mapped_info) {
atm->atm_mapped_info->interrupt_count++;
atm->atm_mapped_info->saved_status_reg = intr;
}
/* Awake user thread */
evc_signal(&atm->atm_eventcounter);
/* NOTE: INTERRUPTS ARE DISABLED. */
}
atm_intr_occurred()
{
atm_nintrs++;
}
atm_output(dev, ior)
int dev;
io_req_t ior;
{
}
atm_start(unit)
int unit;
{
}
atm_open(dev, flag, ior)
int dev;
int flag;
io_req_t ior;
{
register int unit = dev;
register atm_softc_t *atm = &atm_softc[unit];
if (unit >= NATM)
return EINVAL;
if (!atm->atm_dev)
return ENXIO;
return KERN_SUCCESS;
}
atm_close(dev, flag)
int dev;
{
}
atm_read(dev, ior)
int dev;
io_req_t ior;
{
}
atm_write(dev, ior)
int dev;
io_req_t ior;
{
}
atm_get_status(dev, flavor, status, status_count)
int dev;
int flavor;
dev_status_t status; /* pointer to OUT array */
natural_t *status_count; /* out */
{
switch (flavor) {
case NET_STATUS:
{
register struct net_status *ns = (struct net_status *)status;
ns->min_packet_size = sizeof(struct sar_data);
ns->max_packet_size = sizeof(struct sar_data);
ns->header_format = 999; /* XX */
ns->header_size = sizeof(int); /* XX */
ns->address_size = 0;
ns->flags = 0;
ns->mapped_size = sizeof(struct atm_device) + PAGE_SIZE;
*status_count = NET_STATUS_COUNT;
break;
}
case NET_ADDRESS:
/* This would be a good place for it */
default:
return (D_INVALID_OPERATION);
}
return (D_SUCCESS);
}
atm_set_status(dev, flavor, status, status_count)
int dev;
int flavor;
dev_status_t status;
natural_t status_count;
{
}
atm_mmap(dev, off, prot)
int dev;
vm_offset_t off;
int prot;
{
int unit = dev;
vm_offset_t addr;
/*
* Layout of mapped area is:
* 000 -- FA_END: DEVICE
* FA_END -- FA_END + PAGE_SIZE: SHARED STATE
*/
if (off < sizeof(struct atm_device)) {
addr = K1SEG_TO_PHYS((vm_offset_t)(atm_softc[unit].atm_dev)) + off;
} else if (off < sizeof(struct atm_device) + PAGE_SIZE) {
addr = K0SEG_TO_PHYS(atm_softc[unit].atm_mapped_info);
} else return -1;
return mips_btop(addr);
}
atm_setinput(dev, receive_port, priority, filter, filter_count)
int dev;
ipc_port_t receive_port;
int priority;
/*filter_t *filter;*/
natural_t filter_count;
{
}
atm_restart(ifp)
/* register struct ifnet *ifp; */
{
}
atm_portdeath(dev, port)
int dev;
mach_port_t port;
{
}
#endif NATM > 0
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.