diff options
Diffstat (limited to 'chips/atm.c')
-rw-r--r-- | chips/atm.c | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/chips/atm.c b/chips/atm.c new file mode 100644 index 0000000..165cd23 --- /dev/null +++ b/chips/atm.c @@ -0,0 +1,302 @@ +/* + * 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 Software.Distribution@CS.CMU.EDU + * 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 + + + + + |