PERFORCE change 84363 for review
Peter Wemm
peter at FreeBSD.org
Tue Sep 27 10:46:42 PDT 2005
http://perforce.freebsd.org/chv.cgi?CH=84363
Change 84363 by peter at peter_daintree on 2005/09/27 17:45:52
IFC @84362
Affected files ...
.. //depot/projects/hammer/etc/rc.d/localpkg#4 integrate
.. //depot/projects/hammer/release/pc98/boot_crunch.conf#7 integrate
.. //depot/projects/hammer/sys/alpha/include/atomic.h#11 integrate
.. //depot/projects/hammer/sys/amd64/include/atomic.h#23 integrate
.. //depot/projects/hammer/sys/arm/include/atomic.h#11 integrate
.. //depot/projects/hammer/sys/dev/cardbus/cardbus.c#20 integrate
.. //depot/projects/hammer/sys/dev/cp/if_cp.c#21 integrate
.. //depot/projects/hammer/sys/dev/ctau/if_ct.c#22 integrate
.. //depot/projects/hammer/sys/dev/cx/if_cx.c#28 integrate
.. //depot/projects/hammer/sys/dev/fxp/if_fxp.c#51 integrate
.. //depot/projects/hammer/sys/dev/fxp/if_fxpvar.h#15 integrate
.. //depot/projects/hammer/sys/dev/ips/ips_commands.c#14 integrate
.. //depot/projects/hammer/sys/fs/fifofs/fifo_vnops.c#32 integrate
.. //depot/projects/hammer/sys/i386/include/atomic.h#11 integrate
.. //depot/projects/hammer/sys/ia64/include/atomic.h#4 integrate
.. //depot/projects/hammer/sys/kern/init_sysent.c#47 integrate
.. //depot/projects/hammer/sys/kern/syscalls.c#45 integrate
.. //depot/projects/hammer/sys/kern/syscalls.master#45 integrate
.. //depot/projects/hammer/sys/modules/Makefile#86 integrate
.. //depot/projects/hammer/sys/pc98/conf/GENERIC#35 integrate
.. //depot/projects/hammer/sys/pc98/conf/GENERIC.hints#12 integrate
.. //depot/projects/hammer/sys/pc98/conf/NOTES#49 integrate
.. //depot/projects/hammer/sys/powerpc/include/atomic.h#8 integrate
.. //depot/projects/hammer/sys/sparc64/include/atomic.h#5 integrate
.. //depot/projects/hammer/sys/sys/syscall.h#44 integrate
.. //depot/projects/hammer/sys/sys/syscall.mk#44 integrate
.. //depot/projects/hammer/sys/sys/sysproto.h#44 integrate
.. //depot/projects/hammer/usr.bin/make/make.1#25 integrate
.. //depot/projects/hammer/usr.bin/netstat/if.c#10 integrate
.. //depot/projects/hammer/usr.sbin/sysinstall/Makefile#10 integrate
.. //depot/projects/hammer/usr.sbin/sysinstall/sysinstall.h#20 integrate
Differences ...
==== //depot/projects/hammer/etc/rc.d/localpkg#4 (text+ko) ====
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# $FreeBSD: src/etc/rc.d/localpkg,v 1.5 2004/10/07 13:55:26 mtm Exp $
+# $FreeBSD: src/etc/rc.d/localpkg,v 1.6 2005/09/27 02:05:55 brooks Exp $
#
# PROVIDE: localpkg
@@ -53,13 +53,12 @@
pkg_stop()
{
- echo -n 'Shutting down daemon processes:'
-
# For each dir in $local_startup, search for init scripts matching *.sh
case ${local_startup} in
[Nn][Oo] | '')
;;
*)
+ echo -n 'Shutting down daemon processes:'
slist=""
if [ -z "${script_name_sep}" ]; then
script_name_sep=" "
==== //depot/projects/hammer/release/pc98/boot_crunch.conf#7 (text+ko) ====
@@ -1,4 +1,4 @@
-# $FreeBSD: src/release/pc98/boot_crunch.conf,v 1.59 2004/10/01 07:54:37 ru Exp $
+# $FreeBSD: src/release/pc98/boot_crunch.conf,v 1.60 2005/09/27 13:10:23 nyan Exp $
buildopts -DRELEASE_CRUNCH -Dlint
@@ -34,10 +34,8 @@
ln minigzip gunzip
ln minigzip zcat
-srcdirs /usr/src/usr.sbin /usr/src/usr.sbin/pccard
+srcdirs /usr/src/usr.sbin
progs arp
-progs pccardc
-progs pccardd
progs ppp
progs sysinstall
==== //depot/projects/hammer/sys/alpha/include/atomic.h#11 (text+ko) ====
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/sys/alpha/include/atomic.h,v 1.23 2005/09/15 19:31:22 jhb Exp $
+ * $FreeBSD: src/sys/alpha/include/atomic.h,v 1.24 2005/09/27 17:39:09 jhb Exp $
*/
#ifndef _MACHINE_ATOMIC_H_
@@ -365,6 +365,27 @@
return (atomic_cmpset_64(p, cmpval, newval));
}
+/*
+ * Atomically add the value of v to the integer pointed to by p and return
+ * the previous value of *p.
+ */
+static __inline u_int
+atomic_fetchadd_32(volatile u_int32_t *p, u_int32_t v)
+{
+ u_int32_t value, temp;
+
+#ifdef __GNUCLIKE_ASM
+ __asm __volatile (
+ "1:\tldl_l %0, %1\n\t" /* load old value */
+ "addl %0, %3, %2\n\t" /* calculate new value */
+ "stl_c %2, %1\n\t" /* attempt to store */
+ "beq %2, 1b\n" /* spin if failed */
+ : "=&r" (value), "=m" (*p), "=r" (temp)
+ : "r" (v), "m" (*p));
+#endif
+ return (value);
+}
+
/* Operations on chars. */
#define atomic_set_char atomic_set_8
#define atomic_set_acq_char atomic_set_acq_8
@@ -412,6 +433,7 @@
#define atomic_load_acq_int atomic_load_acq_32
#define atomic_store_rel_int atomic_store_rel_32
#define atomic_readandclear_int atomic_readandclear_32
+#define atomic_fetchadd_int atomic_fetchadd_32
/* Operations on longs. */
#define atomic_set_long atomic_set_64
==== //depot/projects/hammer/sys/amd64/include/atomic.h#23 (text+ko) ====
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/sys/amd64/include/atomic.h,v 1.38 2005/09/15 19:31:22 jhb Exp $
+ * $FreeBSD: src/sys/amd64/include/atomic.h,v 1.39 2005/09/27 17:39:10 jhb Exp $
*/
#ifndef _MACHINE_ATOMIC_H_
#define _MACHINE_ATOMIC_H_
@@ -73,6 +73,7 @@
int atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src);
int atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src);
+u_int atomic_fetchadd_int(volatile u_int *p, u_int v);
#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \
u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p); \
@@ -154,6 +155,25 @@
return (res);
}
+/*
+ * Atomically add the value of v to the integer pointed to by p and return
+ * the previous value of *p.
+ */
+static __inline u_int
+atomic_fetchadd_int(volatile u_int *p, u_int v)
+{
+
+ __asm __volatile (
+ " " __XSTRING(MPLOCKED) " "
+ " xaddl %0, %1 ; "
+ "# atomic_fetchadd_int"
+ : "+r" (v), /* 0 (result) */
+ "=m" (*p) /* 1 */
+ : "m" (*p)); /* 2 */
+
+ return (v);
+}
+
#if defined(_KERNEL) && !defined(SMP)
/*
@@ -375,6 +395,7 @@
#define atomic_cmpset_acq_32 atomic_cmpset_acq_int
#define atomic_cmpset_rel_32 atomic_cmpset_rel_int
#define atomic_readandclear_32 atomic_readandclear_int
+#define atomic_fetchadd_32 atomic_fetchadd_int
/* Operations on 64-bit quad words. */
#define atomic_set_64 atomic_set_long
==== //depot/projects/hammer/sys/arm/include/atomic.h#11 (text+ko) ====
@@ -33,7 +33,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: src/sys/arm/include/atomic.h,v 1.10 2005/07/27 20:01:44 jhb Exp $
+ * $FreeBSD: src/sys/arm/include/atomic.h,v 1.11 2005/09/27 17:39:10 jhb Exp $
*/
#ifndef _MACHINE_ATOMIC_H_
@@ -127,6 +127,19 @@
__with_interrupts_disabled(*p -= val);
}
+static __inline uint32_t
+atomic_fetchadd_32(volatile uint32_t *p, uint32_t v)
+{
+ uint32_t value;
+
+ __with_interrupts_disabled(
+ {
+ value = *p;
+ *p += v;
+ });
+ return (value);
+}
+
#else /* !_KERNEL */
static __inline u_int32_t
@@ -240,6 +253,30 @@
: "=r" (ras_start), "=r" (start), "+r" (address), "+r" (clearmask));
}
+
+static __inline uint32_t
+atomic_fetchadd_32(volatile uint32_t *p, uint32_t v)
+{
+ uint32_t ras_start, start;
+
+ __asm __volatile("1:\n"
+ "mov %0, #0xe0000008\n"
+ "adr %1, 2f\n"
+ "str %1, [%0]\n"
+ "adr %1, 1b\n"
+ "mov %0, #0xe0000004\n"
+ "str %1, [%0]\n"
+ "ldr %1, %2\n"
+ "add %3, %1, %3\n"
+ "str %3, %2\n"
+ "2:\n"
+ "mov %3, #0\n"
+ "str %3, [%0]\n"
+ : "=r" (ras_start), "=r" (start), "=m" (*p), "+r" (v));
+ return (start);
+}
+
+
#endif /* _KERNEL */
static __inline int
@@ -291,5 +328,6 @@
#define atomic_store_ptr atomic_store_32
#define atomic_cmpset_ptr atomic_cmpset_32
#define atomic_set_ptr atomic_set_32
+#define atomic_fetchadd_int atomic_fetchadd_32
#endif /* _MACHINE_ATOMIC_H_ */
==== //depot/projects/hammer/sys/dev/cardbus/cardbus.c#20 (text+ko) ====
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/cardbus/cardbus.c,v 1.52 2005/03/18 05:19:49 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/cardbus/cardbus.c,v 1.53 2005/09/27 13:33:46 ru Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -360,8 +360,8 @@
bus_release_resource(cbdev, SYS_RES_IRQ, rid, res);
resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid, start, end,
1);
- dinfo->pci.cfg.intline = rman_get_start(res);
- pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1);
+ dinfo->pci.cfg.intline = start;
+ pci_write_config(child, PCIR_INTLINE, start, 1);
free(barlist, M_DEVBUF);
return (0);
==== //depot/projects/hammer/sys/dev/cp/if_cp.c#21 (text+ko) ====
@@ -22,7 +22,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/cp/if_cp.c,v 1.27 2005/09/19 03:10:16 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/cp/if_cp.c,v 1.29 2005/09/27 16:57:44 rik Exp $");
#include <sys/param.h>
#include <sys/ucred.h>
@@ -184,6 +184,817 @@
static int cp_destroy = 0;
+static int cp_open (struct cdev *dev, int oflags, int devtype, struct thread *td);
+static int cp_close (struct cdev *dev, int fflag, int devtype, struct thread *td);
+static int cp_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td);
+static struct cdevsw cp_cdevsw = {
+ .d_version = D_VERSION,
+ .d_open = cp_open,
+ .d_close = cp_close,
+ .d_ioctl = cp_ioctl,
+ .d_name = "cp",
+ .d_flags = D_NEEDGIANT,
+};
+
+/*
+ * Print the mbuf chain, for debug purposes only.
+ */
+static void printmbuf (struct mbuf *m)
+{
+ printf ("mbuf:");
+ for (; m; m=m->m_next) {
+ if (m->m_flags & M_PKTHDR)
+ printf (" HDR %d:", m->m_pkthdr.len);
+ if (m->m_flags & M_EXT)
+ printf (" EXT:");
+ printf (" %d", m->m_len);
+ }
+ printf ("\n");
+}
+
+/*
+ * Make an mbuf from data.
+ */
+static struct mbuf *makembuf (void *buf, unsigned len)
+{
+ struct mbuf *m;
+
+ MGETHDR (m, M_DONTWAIT, MT_DATA);
+ if (! m)
+ return 0;
+ MCLGET (m, M_DONTWAIT);
+ if (! (m->m_flags & M_EXT)) {
+ m_freem (m);
+ return 0;
+ }
+ m->m_pkthdr.len = m->m_len = len;
+ bcopy (buf, mtod (m, caddr_t), len);
+ return m;
+}
+
+static int cp_probe (device_t dev)
+{
+ if ((pci_get_vendor (dev) == cp_vendor_id) &&
+ (pci_get_device (dev) == cp_device_id)) {
+ device_set_desc (dev, "Cronyx-Tau-PCI serial adapter");
+ return BUS_PROBE_DEFAULT;
+ }
+ return ENXIO;
+}
+
+static void cp_timeout (void *arg)
+{
+ drv_t *d;
+ int s, i, k;
+
+ for (i = 0; i < NBRD; ++i) {
+ if (adapter[i] == NULL)
+ continue;
+ for (k = 0; k < NCHAN; ++k) {
+ s = splimp ();
+ if (cp_destroy) {
+ splx (s);
+ return;
+ }
+ d = channel[i * NCHAN + k];
+ if (!d) {
+ splx (s);
+ continue;
+ }
+ CP_LOCK ((bdrv_t *)d->board->sys);
+ switch (d->chan->type) {
+ case T_G703:
+ cp_g703_timer (d->chan);
+ break;
+ case T_E1:
+ cp_e1_timer (d->chan);
+ break;
+ case T_E3:
+ case T_T3:
+ case T_STS1:
+ cp_e3_timer (d->chan);
+ break;
+ default:
+ break;
+ }
+ CP_UNLOCK ((bdrv_t *)d->board->sys);
+ splx (s);
+ }
+ }
+ s = splimp ();
+ if (!cp_destroy)
+ callout_reset (&timeout_handle, hz, cp_timeout, 0);
+ splx (s);
+}
+
+static void cp_led_off (void *arg)
+{
+ cp_board_t *b = arg;
+ bdrv_t *bd = (bdrv_t *) b->sys;
+ int s;
+ s = splimp ();
+ if (cp_destroy) {
+ splx (s);
+ return;
+ }
+ CP_LOCK (bd);
+ cp_led (b, 0);
+ CP_UNLOCK (bd);
+ splx (s);
+}
+
+static void cp_intr (void *arg)
+{
+ bdrv_t *bd = arg;
+ cp_board_t *b = bd->board;
+#ifndef NETGRAPH
+ int i;
+#endif
+ int s = splimp ();
+ if (cp_destroy) {
+ splx (s);
+ return;
+ }
+ CP_LOCK (bd);
+ /* Check if we are ready */
+ if (b->sys == NULL) {
+ /* Not we are not, just cleanup. */
+ cp_interrupt_poll (b, 1);
+ CP_UNLOCK (bd);
+ return;
+ }
+ /* Turn LED on. */
+ cp_led (b, 1);
+
+ cp_interrupt (b);
+
+ /* Turn LED off 50 msec later. */
+ callout_reset (&led_timo[b->num], hz/20, cp_led_off, b);
+ CP_UNLOCK (bd);
+ splx (s);
+
+#ifndef NETGRAPH
+ /* Pass packets in a lock-free state */
+ for (i = 0; i < NCHAN && b->chan[i].type; i++) {
+ drv_t *d = b->chan[i].sys;
+ struct mbuf *m;
+ if (!d || !d->running)
+ continue;
+ while (_IF_QLEN(&d->queue)) {
+ IF_DEQUEUE (&d->queue,m);
+ if (!m)
+ continue;
+ sppp_input (d->ifp, m);
+ }
+ }
+#endif
+}
+
+static void
+cp_bus_dmamap_addr (void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+ unsigned long *addr;
+
+ if (error)
+ return;
+
+ KASSERT(nseg == 1, ("too many DMA segments, %d should be 1", nseg));
+ addr = arg;
+ *addr = segs->ds_addr;
+}
+
+static int
+cp_bus_dma_mem_alloc (int bnum, int cnum, cp_dma_mem_t *dmem)
+{
+ int error;
+
+ error = bus_dma_tag_create (NULL, 16, 0, BUS_SPACE_MAXADDR_32BIT,
+ BUS_SPACE_MAXADDR, NULL, NULL, dmem->size, 1,
+ dmem->size, 0, NULL, NULL, &dmem->dmat);
+ if (error) {
+ if (cnum >= 0) printf ("cp%d-%d: ", bnum, cnum);
+ else printf ("cp%d: ", bnum);
+ printf ("couldn't allocate tag for dma memory\n");
+ return 0;
+ }
+ error = bus_dmamem_alloc (dmem->dmat, (void **)&dmem->virt,
+ BUS_DMA_NOWAIT | BUS_DMA_ZERO, &dmem->mapp);
+ if (error) {
+ if (cnum >= 0) printf ("cp%d-%d: ", bnum, cnum);
+ else printf ("cp%d: ", bnum);
+ printf ("couldn't allocate mem for dma memory\n");
+ bus_dma_tag_destroy (dmem->dmat);
+ return 0;
+ }
+ error = bus_dmamap_load (dmem->dmat, dmem->mapp, dmem->virt,
+ dmem->size, cp_bus_dmamap_addr, &dmem->phys, 0);
+ if (error) {
+ if (cnum >= 0) printf ("cp%d-%d: ", bnum, cnum);
+ else printf ("cp%d: ", bnum);
+ printf ("couldn't load mem map for dma memory\n");
+ bus_dmamem_free (dmem->dmat, dmem->virt, dmem->mapp);
+ bus_dma_tag_destroy (dmem->dmat);
+ return 0;
+ }
+ return 1;
+}
+
+static void
+cp_bus_dma_mem_free (cp_dma_mem_t *dmem)
+{
+ bus_dmamap_unload (dmem->dmat, dmem->mapp);
+ bus_dmamem_free (dmem->dmat, dmem->virt, dmem->mapp);
+ bus_dma_tag_destroy (dmem->dmat);
+}
+
+/*
+ * Called if the probe succeeded.
+ */
+static int cp_attach (device_t dev)
+{
+ bdrv_t *bd = device_get_softc (dev);
+ int unit = device_get_unit (dev);
+ char *cp_ln = CP_LOCK_NAME;
+ unsigned short res;
+ vm_offset_t vbase;
+ int rid, error;
+ cp_board_t *b;
+ cp_chan_t *c;
+ drv_t *d;
+ int s = splimp ();
+
+ b = malloc (sizeof(cp_board_t), M_DEVBUF, M_WAITOK);
+ if (!b) {
+ printf ("cp%d: couldn't allocate memory\n", unit);
+ splx (s);
+ return (ENXIO);
+ }
+ bzero (b, sizeof(cp_board_t));
+
+ bd->board = b;
+ rid = PCIR_BAR(0);
+ bd->cp_res = bus_alloc_resource (dev, SYS_RES_MEMORY, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (! bd->cp_res) {
+ printf ("cp%d: cannot map memory\n", unit);
+ free (b, M_DEVBUF);
+ splx (s);
+ return (ENXIO);
+ }
+ vbase = (vm_offset_t) rman_get_virtual (bd->cp_res);
+
+ cp_ln[2] = '0' + unit;
+ mtx_init (&bd->cp_mtx, cp_ln, MTX_NETWORK_LOCK, MTX_DEF|MTX_RECURSE);
+ res = cp_init (b, unit, (u_char*) vbase);
+ if (res) {
+ printf ("cp%d: can't init, error code:%x\n", unit, res);
+ bus_release_resource (dev, SYS_RES_MEMORY, PCIR_BAR(0), bd->cp_res);
+ free (b, M_DEVBUF);
+ splx (s);
+ return (ENXIO);
+ }
+
+ bd->dmamem.size = sizeof(cp_qbuf_t);
+ if (! cp_bus_dma_mem_alloc (unit, -1, &bd->dmamem)) {
+ free (b, M_DEVBUF);
+ splx (s);
+ return (ENXIO);
+ }
+ CP_LOCK (bd);
+ cp_reset (b, bd->dmamem.virt, bd->dmamem.phys);
+ CP_UNLOCK (bd);
+
+ rid = 0;
+ bd->cp_irq = bus_alloc_resource (dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (! bd->cp_irq) {
+ cp_destroy = 1;
+ printf ("cp%d: cannot map interrupt\n", unit);
+ bus_release_resource (dev, SYS_RES_MEMORY,
+ PCIR_BAR(0), bd->cp_res);
+ mtx_destroy (&bd->cp_mtx);
+ free (b, M_DEVBUF);
+ splx (s);
+ return (ENXIO);
+ }
+ callout_init (&led_timo[unit], cp_mpsafenet ? CALLOUT_MPSAFE : 0);
+ error = bus_setup_intr (dev, bd->cp_irq,
+ INTR_TYPE_NET|(cp_mpsafenet?INTR_MPSAFE:0),
+ cp_intr, bd, &bd->cp_intrhand);
+ if (error) {
+ cp_destroy = 1;
+ printf ("cp%d: cannot set up irq\n", unit);
+ bus_release_resource (dev, SYS_RES_IRQ, 0, bd->cp_irq);
+ bus_release_resource (dev, SYS_RES_MEMORY,
+ PCIR_BAR(0), bd->cp_res);
+ mtx_destroy (&bd->cp_mtx);
+ free (b, M_DEVBUF);
+ splx (s);
+ return (ENXIO);
+ }
+ printf ("cp%d: %s, clock %ld MHz\n", unit, b->name, b->osc / 1000000);
+
+ for (c = b->chan; c < b->chan + NCHAN; ++c) {
+ if (! c->type)
+ continue;
+ d = &bd->channel[c->num];
+ d->dmamem.size = sizeof(cp_buf_t);
+ if (! cp_bus_dma_mem_alloc (unit, c->num, &d->dmamem))
+ continue;
+ channel [b->num*NCHAN + c->num] = d;
+ sprintf (d->name, "cp%d.%d", b->num, c->num);
+ d->board = b;
+ d->chan = c;
+ c->sys = d;
+#ifdef NETGRAPH
+ if (ng_make_node_common (&typestruct, &d->node) != 0) {
+ printf ("%s: cannot make common node\n", d->name);
+ d->node = NULL;
+ continue;
+ }
+ NG_NODE_SET_PRIVATE (d->node, d);
+ sprintf (d->nodename, "%s%d", NG_CP_NODE_TYPE,
+ c->board->num*NCHAN + c->num);
+ if (ng_name_node (d->node, d->nodename)) {
+ printf ("%s: cannot name node\n", d->nodename);
+ NG_NODE_UNREF (d->node);
+ continue;
+ }
+ d->queue.ifq_maxlen = IFQ_MAXLEN;
+ d->hi_queue.ifq_maxlen = IFQ_MAXLEN;
+ mtx_init (&d->queue.ifq_mtx, "cp_queue", NULL, MTX_DEF);
+ mtx_init (&d->hi_queue.ifq_mtx, "cp_queue_hi", NULL, MTX_DEF);
+ callout_init (&d->timeout_handle,
+ cp_mpsafenet ? CALLOUT_MPSAFE : 0);
+#else /*NETGRAPH*/
+ d->ifp = if_alloc(IFT_PPP);
+ if (d->ifp == NULL) {
+ printf ("%s: cannot if_alloc() interface\n", d->name);
+ continue;
+ }
+ d->ifp->if_softc = d;
+ if_initname (d->ifp, "cp", b->num * NCHAN + c->num);
+ d->ifp->if_mtu = PP_MTU;
+ d->ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
+ if (!cp_mpsafenet)
+ d->ifp->if_flags |= IFF_NEEDSGIANT;
+ d->ifp->if_ioctl = cp_sioctl;
+ d->ifp->if_start = cp_ifstart;
+ d->ifp->if_watchdog = cp_ifwatchdog;
+ d->ifp->if_init = cp_initialize;
+ d->queue.ifq_maxlen = NRBUF;
+ mtx_init (&d->queue.ifq_mtx, "cp_queue", NULL, MTX_DEF);
+ sppp_attach (d->ifp);
+ if_attach (d->ifp);
+ IFP2SP(d->ifp)->pp_tlf = cp_tlf;
+ IFP2SP(d->ifp)->pp_tls = cp_tls;
+ /* If BPF is in the kernel, call the attach for it.
+ * The header size of PPP or Cisco/HDLC is 4 bytes. */
+ bpfattach (d->ifp, DLT_PPP, 4);
+#endif /*NETGRAPH*/
+ cp_start_e1 (c);
+ cp_start_chan (c, 1, 1, d->dmamem.virt, d->dmamem.phys);
+
+ /* Register callback functions. */
+ cp_register_transmit (c, &cp_transmit);
+ cp_register_receive (c, &cp_receive);
+ cp_register_error (c, &cp_error);
+ d->devt = make_dev (&cp_cdevsw, b->num*NCHAN+c->num, UID_ROOT,
+ GID_WHEEL, 0600, "cp%d", b->num*NCHAN+c->num);
+ }
+ CP_LOCK (bd);
+ b->sys = bd;
+ adapter[unit] = b;
+ CP_UNLOCK (bd);
+ splx (s);
+ return 0;
+}
+
+static int cp_detach (device_t dev)
+{
+ bdrv_t *bd = device_get_softc (dev);
+ cp_board_t *b = bd->board;
+ cp_chan_t *c;
+ int s;
+
+ KASSERT (mtx_initialized (&bd->cp_mtx), ("cp mutex not initialized"));
+ s = splimp ();
+ CP_LOCK (bd);
+ /* Check if the device is busy (open). */
+ for (c = b->chan; c < b->chan + NCHAN; ++c) {
+ drv_t *d = (drv_t*) c->sys;
+
+ if (! d || ! d->chan->type)
+ continue;
+ if (d->running) {
+ CP_UNLOCK (bd);
+ splx (s);
+ return EBUSY;
+ }
+ }
+
+ /* Ok, we can unload driver */
+ /* At first we should stop all channels */
+ for (c = b->chan; c < b->chan + NCHAN; ++c) {
+ drv_t *d = (drv_t*) c->sys;
+
+ if (! d || ! d->chan->type)
+ continue;
+
+ cp_stop_chan (c);
+ cp_stop_e1 (c);
+ cp_set_dtr (d->chan, 0);
+ cp_set_rts (d->chan, 0);
+ }
+
+ /* Reset the adapter. */
+ cp_destroy = 1;
+ cp_interrupt_poll (b, 1);
+ cp_led_off (b);
+ cp_reset (b, 0 ,0);
+ callout_stop (&led_timo[b->num]);
+
+ /* Disable the interrupt request. */
+ bus_teardown_intr (dev, bd->cp_irq, bd->cp_intrhand);
+
+ for (c=b->chan; c<b->chan+NCHAN; ++c) {
+ drv_t *d = (drv_t*) c->sys;
+
+ if (! d || ! d->chan->type)
+ continue;
+#ifndef NETGRAPH
+ /* Detach from the packet filter list of interfaces. */
+ bpfdetach (d->ifp);
+
+ /* Detach from the sync PPP list. */
+ sppp_detach (d->ifp);
+
+ /* Detach from the system list of interfaces. */
+ if_detach (d->ifp);
+ if_free (d->ifp);
+ IF_DRAIN (&d->queue);
+ mtx_destroy (&d->queue.ifq_mtx);
+#else
+ if (d->node) {
+ ng_rmnode_self (d->node);
+ NG_NODE_UNREF (d->node);
+ d->node = NULL;
+ }
+ mtx_destroy (&d->queue.ifq_mtx);
+ mtx_destroy (&d->hi_queue.ifq_mtx);
+#endif
+ destroy_dev (d->devt);
+ }
+
+ b->sys = NULL;
+ CP_UNLOCK (bd);
+
+ bus_deactivate_resource (dev, SYS_RES_IRQ, 0, bd->cp_irq);
+ bus_release_resource (dev, SYS_RES_IRQ, 0, bd->cp_irq);
+ bus_release_resource (dev, SYS_RES_MEMORY, PCIR_BAR(0), bd->cp_res);
+
+ CP_LOCK (bd);
+ cp_led_off (b);
+ CP_UNLOCK (bd);
+ callout_drain (&led_timo[b->num]);
+ splx (s);
+
+ s = splimp ();
+ for (c = b->chan; c < b->chan + NCHAN; ++c) {
+ drv_t *d = (drv_t*) c->sys;
+
+ if (! d || ! d->chan->type)
+ continue;
+ channel [b->num*NCHAN + c->num] = 0;
+ /* Deallocate buffers. */
+ cp_bus_dma_mem_free (&d->dmamem);
+ }
+ adapter [b->num] = 0;
+ cp_bus_dma_mem_free (&bd->dmamem);
+ free (b, M_DEVBUF);
+ splx (s);
+ mtx_destroy (&bd->cp_mtx);
+ return 0;
+}
+
+#ifndef NETGRAPH
+static void cp_ifstart (struct ifnet *ifp)
+{
+ drv_t *d = ifp->if_softc;
+ bdrv_t *bd = d->board->sys;
+
+ CP_LOCK (bd);
+ cp_start (d);
+ CP_UNLOCK (bd);
+}
+
+static void cp_ifwatchdog (struct ifnet *ifp)
+{
+ drv_t *d = ifp->if_softc;
+
+ cp_watchdog (d);
+}
+
+static void cp_tlf (struct sppp *sp)
+{
+ drv_t *d = SP2IFP(sp)->if_softc;
+
+ CP_DEBUG2 (d, ("cp_tlf\n"));
+ /* XXXRIK: Don't forget to protect them by LOCK, or kill them. */
+/* cp_set_dtr (d->chan, 0);*/
+/* cp_set_rts (d->chan, 0);*/
+ if (!(sp->pp_flags & PP_FR) && !(d->ifp->if_flags & PP_CISCO))
+ sp->pp_down (sp);
+}
+
+static void cp_tls (struct sppp *sp)
+{
+ drv_t *d = SP2IFP(sp)->if_softc;
+
+ CP_DEBUG2 (d, ("cp_tls\n"));
+ if (!(sp->pp_flags & PP_FR) && !(d->ifp->if_flags & PP_CISCO))
+ sp->pp_up (sp);
+}
+
+/*
+ * Process an ioctl request.
+ */
+static int cp_sioctl (struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+ drv_t *d = ifp->if_softc;
+ bdrv_t *bd = d->board->sys;
+ int error, s, was_up, should_be_up;
+
+ was_up = (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0;
+ error = sppp_ioctl (ifp, cmd, data);
+
+ if (error)
+ return error;
+
+ if (! (ifp->if_flags & IFF_DEBUG))
+ d->chan->debug = 0;
+ else if (! d->chan->debug)
+ d->chan->debug = 1;
+
+ switch (cmd) {
+ default: CP_DEBUG2 (d, ("ioctl 0x%lx\n", cmd)); return 0;
+ case SIOCADDMULTI: CP_DEBUG2 (d, ("ioctl SIOCADDMULTI\n")); return 0;
+ case SIOCDELMULTI: CP_DEBUG2 (d, ("ioctl SIOCDELMULTI\n")); return 0;
+ case SIOCSIFFLAGS: CP_DEBUG2 (d, ("ioctl SIOCSIFFLAGS\n")); break;
+ case SIOCSIFADDR: CP_DEBUG2 (d, ("ioctl SIOCSIFADDR\n")); break;
+ }
+
+ /* We get here only in case of SIFFLAGS or SIFADDR. */
+ s = splimp ();
+ CP_LOCK (bd);
+ should_be_up = (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0;
+ if (! was_up && should_be_up) {
+ /* Interface goes up -- start it. */
+ cp_up (d);
+ cp_start (d);
+ } else if (was_up && ! should_be_up) {
+ /* Interface is going down -- stop it. */
+/* if ((IFP2SP(ifp)->pp_flags & PP_FR) || (ifp->if_flags & PP_CISCO))*/
+ cp_down (d);
+ }
+ CP_DEBUG (d, ("ioctl 0x%lx p4\n", cmd));
+ CP_UNLOCK (bd);
+ splx (s);
+ return 0;
+}
+
+/*
+ * Initialization of interface.
+ * It seems to be never called by upper level?
+ */
+static void cp_initialize (void *softc)
+{
+ drv_t *d = softc;
+
+ CP_DEBUG (d, ("cp_initialize\n"));
+}
+#endif /*NETGRAPH*/
+
+/*
+ * Stop the interface. Called on splimp().
+ */
+static void cp_down (drv_t *d)
+{
+ CP_DEBUG (d, ("cp_down\n"));
+ /* Interface is going down -- stop it. */
+ cp_set_dtr (d->chan, 0);
+ cp_set_rts (d->chan, 0);
+
+ d->running = 0;
+}
+
+/*
+ * Start the interface. Called on splimp().
+ */
+static void cp_up (drv_t *d)
+{
+ CP_DEBUG (d, ("cp_up\n"));
+ cp_set_dtr (d->chan, 1);
+ cp_set_rts (d->chan, 1);
+ d->running = 1;
+}
+
+/*
+ * Start output on the interface. Get another datagram to send
+ * off of the interface queue, and copy it to the interface
+ * before starting the output.
+ */
+static void cp_send (drv_t *d)
+{
+ struct mbuf *m;
+ u_short len;
+
+ CP_DEBUG2 (d, ("cp_send, tn=%d te=%d\n", d->chan->tn, d->chan->te));
+
+ /* No output if the interface is down. */
+ if (! d->running)
+ return;
+
+ /* No output if the modem is off. */
+ if (! (d->chan->lloop || d->chan->type != T_SERIAL ||
+ cp_get_dsr (d->chan)))
+ return;
+
+ while (cp_transmit_space (d->chan)) {
+ /* Get the packet to send. */
+#ifdef NETGRAPH
+ IF_DEQUEUE (&d->hi_queue, m);
+ if (! m)
+ IF_DEQUEUE (&d->queue, m);
+#else
+ m = sppp_dequeue (d->ifp);
+#endif
+ if (! m)
+ return;
+#ifndef NETGRAPH
+ if (d->ifp->if_bpf)
+ BPF_MTAP (d->ifp, m);
+#endif
+ len = m_length (m, NULL);
+ if (len >= BUFSZ)
+ printf ("%s: too long packet: %d bytes: ",
+ d->name, len);
+ else if (! m->m_next)
+ cp_send_packet (d->chan, (u_char*) mtod (m, caddr_t), len, 0);
+ else {
+ u_char *buf = d->chan->tbuf[d->chan->te];
+ m_copydata (m, 0, len, buf);
+ cp_send_packet (d->chan, buf, len, 0);
+ }
+ m_freem (m);
+ /* Set up transmit timeout, if the transmit ring is not empty.*/
+#ifdef NETGRAPH
+ d->timeout = 10;
+#else
+ d->ifp->if_timer = 10;
+#endif
+ }
+#ifndef NETGRAPH
+ d->ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+#endif
+}
+
+/*
+ * Start output on the interface.
+ * Always called on splimp().
+ */
+static void cp_start (drv_t *d)
+{
+ if (d->running) {
+ if (! d->chan->dtr)
+ cp_set_dtr (d->chan, 1);
+ if (! d->chan->rts)
+ cp_set_rts (d->chan, 1);
+ cp_send (d);
+ }
+}
+
+/*
+ * Handle transmit timeouts.
+ * Recover after lost transmit interrupts.
+ * Always called on splimp().
+ */
+static void cp_watchdog (drv_t *d)
+{
+ bdrv_t *bd = d->board->sys;
+ CP_DEBUG (d, ("device timeout\n"));
+ if (d->running) {
+ int s = splimp ();
+
+ CP_LOCK (bd);
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list