text:
static const char *version =
"cops.c:v0.04 6/7/98 Jay Schulist <jschlst@samba.org>\n";
/*
 *  Sources:
 *      COPS Localtalk SDK. This provides almost all of the information
 *      needed.
 */

/*
 * insmod/modprobe configurable stuff.
 *	- IO Port, choose one your card supports or 0 if you dare.
 *	- IRQ, also choose one your card supports or nothing and let
 *	  the driver figure it out.
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/if_ltalk.h>
#include <linux/delay.h>	/* For udelay() */
#include <linux/atalk.h>
#include <linux/spinlock.h>
#include <linux/bitops.h>

#include <asm/system.h>
#include <asm/io.h>
#include <asm/dma.h>

#include "cops.h"		/* Our Stuff */
#include "cops_ltdrv.h"		/* Firmware code for Tangent type cards. */
#include "cops_ffdrv.h"		/* Firmware code for Dayna type cards. */

/*
 *      The name of the card. Is used for messages and in the requests for
 *      io regions, irqs and dma channels
 */

static const char *cardname = "cops";

#ifdef CONFIG_COPS_DAYNA
static int board_type = DAYNA;	/* Module exported */
#else
static int board_type = TANGENT;
#endif

static int io = 0x240;		/* Default IO for Dayna */
static int irq = 5;		/* Default IRQ */

/*
 *	COPS Autoprobe information.
 *	Right now if port address is right but IRQ is not 5 this will
 *      return a 5 no matter what since we will still get a status response.
 *      Need one more additional check to narrow down after we have gotten
 *      the ioaddr. But since only other possible IRQs is 3 and 4 so no real
 *	hurry on this. I *STRONGLY* recommend using IRQ 5 for your card with
 *	this driver.
 *
 *	This driver has 2 modes and they are: Dayna mode and Tangent mode.
 *	Each mode corresponds with the type of card. It has been found
 *	that there are 2 main types of cards and all other cards are
 *	the same and just have different names or only have minor differences
 *	such as more IO ports. As this driver is tested it will
 *	become more clear on exactly what cards are supported. The driver
 *	defaults to using Dayna mode. To change the drivers mode, simply
 *	select Dayna or Tangent mode when configuring the kernel.
 *
 *      This driver should support:
 *      TANGENT driver mode:
 *              Tangent ATB-II, Novell NL-1000, Daystar Digital LT-200,
 *		COPS LT-1
 *      DAYNA driver mode:
 *              Dayna DL2000/DaynaTalk PC (Half Length), COPS LT-95,
 *		Farallon PhoneNET PC III, Farallon PhoneNET PC II
 *	Other cards possibly supported mode unkown though:
 *		Dayna DL2000 (Full length), COPS LT/M (Micro-Channel)
 *
 *	Cards NOT supported by this driver but supported by the ltpc.c
 *	driver written by Bradford W. Johnson <johns393@maroon.tc.umn.edu>
 *		Farallon PhoneNET PC
 *		Original Apple LocalTalk PC card
 *
 *      N.B.
 *
 *      The Daystar Digital LT200 boards do not support interrupt-driven
 *      IO.  You must specify 'irq=0xff' as a module parameter to invoke
 *      polled mode.  I also believe that the port probing logic is quite
 *      dangerous at best and certainly hopeless for a polled card.  Best to
 *      specify both. - Steve H.
 *
 */

/*
 * Zero terminated list of IO ports to probe.
 */

static unsigned int ports[] = {
	0x240, 0x340, 0x200, 0x210, 0x220, 0x230, 0x260,
	0x2A0, 0x300, 0x310, 0x320, 0x330, 0x350, 0x360,
	0
};

/*
 * Zero terminated list of IRQ ports to probe.
 */

static int cops_irqlist[] = {
	5, 4, 3, 0
};

static struct timer_list cops_timer;

/* use 0 for production, 1 for verification, 2 for debug, 3 for verbose debug */
#ifndef COPS_DEBUG
#define COPS_DEBUG 1
#endif
static unsigned int cops_debug = COPS_DEBUG;

/* The number of low I/O ports used by the card. */
#define COPS_IO_EXTENT       8

/* Information that needs to be kept for each board. */

struct cops_local
{
        struct net_device_stats stats;
        int board;			/* Holds what board type is. */
	int nodeid;			/* Set to 1 once have nodeid. */
        unsigned char node_acquire;	/* Node ID when acquired. */
        struct atalk_addr node_addr;	/* Full node address */
	spinlock_t lock;		/* RX/TX lock */
};

/* Index to functions, as function prototypes. */
static int  cops_probe1 (struct net_device *dev, int ioaddr);
static int  cops_irq (int ioaddr, int board);

static int  cops_open (struct net_device *dev);
static int  cops_jumpstart (struct net_device *dev);
static void cops_reset (struct net_device *dev, int sleep);
static void cops_load (struct net_device *dev);
static int  cops_nodeid (struct net_device *dev, int nodeid);

static irqreturn_t cops_interrupt (int irq, void *dev_id, struct pt_regs *regs);
static void cops_poll (unsigned long ltdev);
static void cops_timeout(struct net_device *dev);
static void cops_rx (struct net_device *dev);
static int  cops_send_packet (struct sk_buff *skb, struct net_device *dev);
static void set_multicast_list (struct net_device *dev);
static int  cops_hard_header (struct sk_buff *skb, struct net_device *dev,
			      unsigned short type, void *daddr, void *saddr,
			      unsigned len);

static int  cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
static int  cops_close (struct net_device *dev);
static struct net_device_stats *cops_get_stats (struct net_device *dev);

static void cleanup_card(struct net_device *dev)
{
	if (dev->irq)
		free_irq(dev->irq, dev);
	release_region(dev->base_addr, COPS_IO_EXTENT);
}

/*
 *      Check for a network adaptor of this type, and return '0' iff one exists.
 *      If dev->base_addr == 0, probe all likely locations.
 *      If dev->base_addr in [1..0x1ff], always return failure.
 *        otherwise go with what we pass in.
 */
struct net_device * __init cops_probe(int unit)
{
	struct net_device *dev;
	unsigned *port;
	int base_addr;
	int err = 0;

	dev = alloc_ltalkdev(sizeof(struct cops_local));
	if (!dev)
		return ERR_PTR(-ENOMEM);

	if (unit >= 0) {
		sprintf(dev->name, "lt%d", unit);
		netdev_boot_setup_check(dev);
		irq = dev->irq;
		base_addr = dev->base_addr;
	} else {
		base_addr = dev->base_addr = io;
	}

	SET_MODULE_OWNER(dev);

	if (base_addr > 0x1ff) {    /* Check a single specified location. */
		err = cops_probe1(dev, base_addr);
	} else if (base_addr != 0) { /* Don't probe at all. */
		err = -ENXIO;
	} else {
		/* FIXME  Does this really work for cards which generate irq?
		 * It's definitely N.G. for polled Tangent. sh
		 * Dayna cards don't autoprobe well at all, but if your card is
		 * at IRQ 5 & IO 0x240 we find it every time. ;) JS
		 */
		for (port = ports; *port && cops_probe1(dev, *port) < 0; port++)
			;
		if (!*port)
			err = -ENODEV;
	}
	if (err)
		goto out;
	err = register_netdev(dev);
	if (err)
		goto out1;
	return dev;
out1:
	cleanup_card(dev);
out:
	free_netdev(dev);
	return ERR_PTR(err);
}

/*
 *      This is the real probe routine. Linux has a history of friendly device
 *      probes on the ISA bus. A good device probes avoids doing writes, and
 *      verifies that the correct device exists and functions.
 */
static int __init cops_probe1(struct net_device *dev, int ioaddr)
{
        struct cops_local *lp;
	static unsigned version_printed;
	int board = board_type;
	int retval;

        if(cops_debug && version_printed++ == 0)
		printk("%s", version);

	/* Grab the region so no one else tries to probe our ioports. */
	if (!request_region(ioaddr, COPS_IO_EXTENT, dev->name))
		return -EBUSY;

        /*
         * Since this board has jumpered interrupts, allocate the interrupt
         * vector now. There is no point in waiting since no other device
         * can use the interrupt, and this marks the irq as busy. Jumpered
         * interrupts are typically not reported by the boards, and we must
         * used AutoIRQ to find them.
	 */
	dev->irq = irq;
	switch (dev->irq)
	{
		case 0:
			/* COPS AutoIRQ routine */
			dev->irq = cops_irq(ioaddr, board);
			if (dev->irq)
				break;
			/* No IRQ found on this port, fallthrough */
		case 1:
			retval = -EINVAL;
			goto err_out;

		/* Fixup for users that don't know that IRQ 2 is really
		 * IRQ 9, or don't know which one to set.
		 */
		case 2:
			dev->irq = 9;
			break;

		/* Polled operation requested. Although irq of zero passed as
		 * a parameter tells the init routines to probe, we'll
		 * overload it to denote polled operation at runtime.
		 */
		case 0xff:
			dev->irq = 0;
			break;

		default:
			break;
	}

	/* Reserve any actual interrupt. */
	if (dev->irq) {
		retval = request_irq(dev->irq, &cops_interrupt, 0, dev->name, dev);
		if (retval)
			goto err_out;
	}

	dev->base_addr = ioaddr;

        lp = netdev_priv(dev);
        memset(lp, 0, sizeof(struct cops_local));
        spin_lock_init(&lp->lock);

	/* Copy local board variable to lp struct. */
	lp->board               = board;

	dev->hard_start_xmit    = cops_send_packet;
	dev->tx_timeout		= cops_timeout;
	dev->watchdog_timeo	= HZ * 2;
	dev->hard_header	= cops_hard_header;
        dev->get_stats          = cops_get_stats;
	dev->open               = cops_open;
        dev->stop               = cops_close;
        dev->do_ioctl           = cops_ioctl;
	dev->set_multicast_list = set_multicast_list;
        dev->mc_list            = NULL;

	/* Tell the user where the card is and what mode we're in. */
	if(board==DAYNA)
		printk("%s: %s at %#3x, using IRQ %d, in Dayna mode.\n",
			dev->name, cardname, ioaddr, dev->irq);
	if(board==TANGENT) {
		if(dev->irq)
			printk("%s: %s at %#3x, IRQ %d, in Tangent mode\n",
				dev->name, cardname, ioaddr, dev->irq);
		else
			printk("%s: %s at %#3x, using polled IO, in Tangent mode.\n",
				dev->name, cardname, ioaddr);

	}
        return 0;

err_out:
	release_region(ioaddr, COPS_IO_EXTENT);
	return retval;
}

static int __init cops_irq (int ioaddr, int board)
{       /*
         * This does not use the IRQ to determine where the IRQ is. We just
         * assume that when we get a correct status response that it's the IRQ.
         * This really just verifies the IO port but since we only have access
         * to such a small number of IRQs (5, 4, 3) this is not bad.
         * This will probably not work for more than one card.
         */
        int irqaddr=0;
        int i, x, status;

        if(board==DAYNA)
        {
                outb(0, ioaddr+DAYNA_RESET);
                inb(ioaddr+DAYNA_RESET);
                mdelay(333);
        }
        if(board==TANGENT)
        {
                inb(ioaddr);
                outb(0, ioaddr);
                outb(0, ioaddr+TANG_RESET);
        }

        for(i=0; cops_irqlist[i] !=0; i++)
        {
                irqaddr = cops_irqlist[i];
                for(x = 0xFFFF; x>0; x --)    /* wait for response */
                {
                        if(board==DAYNA)
                        {
                                status = (inb(ioaddr+DAYNA_CARD_STATUS)&3);
                                if(status == 1)
                                        return irqaddr;
                        }
                        if(board==TANGENT)
                        {
                                if((inb(ioaddr+TANG_CARD_STATUS)& TANG_TX_READY) !=0)
                                        return irqaddr;
                        }
                }
        }
        return 0;       /* no IRQ found */
}

/*
 * Open/initialize the board. This is called (in the current kernel)
 * sometime after booting when the 'ifconfig' program is run.
 */
static int cops_open(struct net_device *dev)
{
    struct cops_local *lp = netdev_priv(dev);

	if(dev->irq==0)
	{
		/*
		 * I don't know if the Dayna-style boards support polled
		 * operation.  For now, only allow it for Tangent.
		 */
		if(lp->board==TANGENT)	/* Poll 20 times per second */
		{
		    init_timer(&cops_timer);
		    cops_timer.function = cops_poll;
		    cops_timer.data 	= (unsigned long)dev;
		    cops_timer.expires 	= jiffies + HZ/20;
		    add_timer(&cops_timer);
		}
		else
		{
			printk(KERN_WARNING "%s: No irq line set\n", dev->name);
			return -EAGAIN;
		}
	}

	cops_jumpstart(dev);	/* Start the card up. */

	netif_start_queue(dev);
        return 0;
}

/*
 *	This allows for a dynamic start/restart of the entire card.
 */
static int cops_jumpstart(struct net_device *dev)
{
	struct cops_local *lp = netdev_priv(dev);

	/*
         *      Once the card has the firmware loaded and has acquired
         *      the nodeid, if it is reset it will lose it all.
         */
        cops_reset(dev,1);	/* Need to reset card before load firmware. */
        cops_load(dev);		/* Load the firmware. */

	/*
	 *	If atalkd already gave us a nodeid we will use that
	 *	one again, else we wait for atalkd to give us a nodeid
	 *	in cops_ioctl. This may cause a problem if someone steals
	 *	our nodeid while we are resetting.
	 */
	if(lp->nodeid == 1)
		cops_nodeid(dev,lp->node_acquire);

	return 0;
}

static void tangent_wait_reset(int ioaddr)
{
	int timeout=0;

	while(timeout++ < 5 && (inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
		mdelay(1);   /* Wait 1 second */
}

/*
 *      Reset the LocalTalk board.
 */
static void cops_reset(struct net_device *dev, int sleep)
{
        struct cops_local *lp = netdev_priv(dev);
        int ioaddr=dev->base_addr;

        if(lp->board==TANGENT)
        {
                inb(ioaddr);		/* Clear request latch. */
                outb(0,ioaddr);		/* Clear the TANG_TX_READY flop. */
                outb(0, ioaddr+TANG_RESET);	/* Reset the adapter. */

		tangent_wait_reset(ioaddr);
                outb(0, ioaddr+TANG_CLEAR_INT);
        }
        if(lp->board==DAYNA)
        {
                outb(0, ioaddr+DAYNA_RESET);	/* Assert the reset port */
                inb(ioaddr+DAYNA_RESET);	/* Clear the reset */
                if(sleep)
                {
                        long snap=jiffies;

			/* Let card finish initializing, about 1/3 second */
	                while(jiffies-snap<HZ/3)
                                schedule();
                }
                else
                        mdelay(333);
        }
	netif_wake_queue(dev);
	return;
}

static void cops_load (struct net_device *dev)
{
        struct ifreq ifr;
        struct ltfirmware *ltf= (struct ltfirmware *)&ifr.ifr_ifru;
        struct cops_local *lp = netdev_priv(dev);
        int ioaddr=dev->base_addr;
	int length, i = 0;

        strcpy(ifr.ifr_name,"lt0");

        /* Get card's firmware code and do some checks on it. */
#ifdef CONFIG_COPS_DAYNA
        if(lp->board==DAYNA)
        {
                ltf->length=sizeof(ffdrv_code);
                ltf->data=ffdrv_code;
        }
        else
#endif
#ifdef CONFIG_COPS_TANGENT
        if(lp->board==TANGENT)
        {
                ltf->length=sizeof(ltdrv_code);
                ltf->data=ltdrv_code;
        }
        else
#endif
	{
		printk(KERN_INFO "%s; unsupported board type.\n", dev->name);
		return;
	}

        /* Check to make sure firmware is correct length. */
        if(lp->board==DAYNA && ltf->length!=5983)
        {
                printk(KERN_WARNING "%s: Firmware is not length of FFDRV.BIN.\n", dev->name);
                return;
        }
        if(lp->board==TANGENT && ltf->length!=2501)
        {
                printk(KERN_WARNING "%s: Firmware is not length of DRVCODE.BIN.\n", dev->name);
                return;
        }

        if(lp->board==DAYNA)
        {
                /*
                 *      We must wait for a status response
                 *      with the DAYNA board.
                 */
                while(++i<65536)
                {
                       if((inb(ioaddr+DAYNA_CARD_STATUS)&3)==1)
                                break;
                }

                if(i==65536)
                        return;
        }

        /*
         *      Upload the firmware and kick. Byte-by-byte works nicely here.
         */
	i=0;
        length = ltf->length;
        while(length--)
        {
                outb(ltf->data[i], ioaddr);
                i++;
        }

	if(cops_debug > 1)
		printk("%s: Uploaded firmware - %d bytes of %d bytes.\n",
			dev->name, i, ltf->length);

        if(lp->board==DAYNA) 	/* Tell Dayna to run the firmware code. */
                outb(1, ioaddr+DAYNA_INT_CARD);
	else			/* Tell Tang to run the firmware code. */
		inb(ioaddr);

        if(lp->board==TANGENT)
        {
                tangent_wait_reset(ioaddr);
                inb(ioaddr);	/* Clear initial ready signal. */
        }

        return;
}

/*
 * 	Get the LocalTalk Nodeid from the card. We can suggest
 *	any nodeid 1-254. The card will try and get that exact
 *	address else we can specify 0 as the nodeid and the card
 *	will autoprobe for a nodeid.
 */
static int cops_nodeid (struct net_device *dev, int nodeid)
{
	struct cops_local *lp = netdev_priv(dev);
	int ioaddr = dev->base_addr;

	if(lp->board == DAYNA)
        {
        	/* Empty any pending adapter responses. */
                while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0)
                {
			outb(0, ioaddr+COPS_CLEAR_INT);	/* Clear interrupts. */
        		if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST)
                		cops_rx(dev);	/* Kick any packets waiting. */
			schedule();
                }

                outb(2, ioaddr);       	/* Output command packet length as 2. */
                outb(0, ioaddr);
                outb(LAP_INIT, ioaddr);	/* Send LAP_INIT command byte. */
                outb(nodeid, ioaddr);  	/* Suggest node address. */
        }

	if(lp->board == TANGENT)
        {
                /* Empty any pending adapter responses. */
                while(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY)
                {
			outb(0, ioaddr+COPS_CLEAR_INT);	/* Clear interrupt. */
                	cops_rx(dev);          	/* Kick out packets waiting. */
			schedule();
                }

		/* Not sure what Tangent does if nodeid picked is used. */
                if(nodeid == 0)	         		/* Seed. */
                	nodeid = jiffies&0xFF;		/* Get a random try */
                outb(2, ioaddr);        		/* Command length LSB */
                outb(0, ioaddr);       			/* Command length MSB */
                outb(LAP_INIT, ioaddr); 		/* Send LAP_INIT byte */
                outb(nodeid, ioaddr); 		  	/* LAP address hint. */
                outb(0xFF, ioaddr);     		/* Int. level to use */
        }

	lp->node_acquire=0;		/* Set nodeid holder to 0. */
        while(lp->node_acquire==0)	/* Get *True* nodeid finally. */
	{
		outb(0, ioaddr+COPS_CLEAR_INT);	/* Clear any interrupt. */

		if(lp->board == DAYNA)
		{
                	if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST)
                		cops_rx(dev);	/* Grab the nodeid put in lp->node_acquire. */
		}
		if(lp->board == TANGENT)
		{
			if(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY)
                                cops_rx(dev);   /* Grab the nodeid put in lp->node_acquire. */
		}
		schedule();
	}

	if(cops_debug > 1)
		printk(KERN_DEBUG "%s: Node ID %d has been acquired.\n",
			dev->name, lp->node_acquire);

	lp->nodeid=1;	/* Set got nodeid to 1. */

        return 0;
}

/*
 *	Poll the Tangent type cards to see if we have work.
 */

static void cops_poll(unsigned long ltdev)
{
	int ioaddr, status;
	int boguscount = 0;

	struct net_device *dev = (struct net_device *)ltdev;

	del_timer(&cops_timer);

	if(dev == NULL)
		return;	/* We've been downed */

	ioaddr = dev->base_addr;
	do {
		status=inb(ioaddr+TANG_CARD_STATUS);
		if(status & TANG_RX_READY)
			cops_rx(dev);
		if(status & TANG_TX_READY)
			netif_wake_queue(dev);
		status = inb(ioaddr+TANG_CARD_STATUS);
	} while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY)));

	/* poll 20 times per second */
	cops_timer.expires = jiffies + HZ/20;
	add_timer(&cops_timer);

	return;
}

/*
 *      The typical workload of the driver:
 *      Handle the network interface interrupts.
 */
static irqreturn_t cops_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
        struct net_device *dev = dev_id;
        struct cops_local *lp;
        int ioaddr, status;
        int boguscount = 0;

        ioaddr = dev->base_addr;
        lp = netdev_priv(dev);

	if(lp->board==DAYNA)
	{
		do {
			outb(0, ioaddr + COPS_CLEAR_INT);
                       	status=inb(ioaddr+DAYNA_CARD_STATUS);
                       	if((status&0x03)==DAYNA_RX_REQUEST)
                       	        cops_rx(dev);
                	netif_wake_queue(dev);
		} while(++boguscount < 20);
	}
	else
	{
		do {
                       	status=inb(ioaddr+TANG_CARD_STATUS);
			if(status & TANG_RX_READY)
				cops_rx(dev);
			if(status & TANG_TX_READY)
				netif_wake_queue(dev);
			status=inb(ioaddr+TANG_CARD_STATUS);
		} while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY)));
	}

        return IRQ_HANDLED;
}

/*
 *      We have a good packet(s), get it/them out of the buffers.
 */
static void cops_rx(struct net_device *dev)
{
        int pkt_len = 0;
        int rsp_type = 0;
        struct sk_buff *skb = NULL;
        struct cops_local *lp = netdev_priv(dev);
        int ioaddr = dev->base_addr;
        int boguscount = 0;
        unsigned long flags;

	spin_lock_irqsave(&lp->lock, flags);

        if(lp->board==DAYNA)
        {
                outb(0, ioaddr);                /* Send out Zero length. */
                outb(0, ioaddr);
                outb(DATA_READ, ioaddr);        /* Send read command out. */

                /* Wait for DMA to turn around. */
                while(++boguscount<1000000)
                {
			barrier();
                        if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_READY)
                                break;
                }

                if(boguscount==1000000)
                {
                        printk(KERN_WARNING "%s: DMA timed out.\n",dev->name);
			spin_unlock_irqrestore(&lp->lock, flags);
                        return;
                }
        }

        /* Get response length. */
	if(lp->board==DAYNA)
        	pkt_len = inb(ioaddr) & 0xFF;
	else
		pkt_len = inb(ioaddr) & 0x00FF;
        pkt_len |= (inb(ioaddr) << 8);
        /* Input IO code. */
        rsp_type=inb(ioaddr);

        /* Malloc up new buffer. */
        skb = dev_alloc_skb(pkt_len);
        if(skb == NULL)
        {
                printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n",
			dev->name);
                lp->stats.rx_dropped++;
                while(pkt_len--)        /* Discard packet */
                        inb(ioaddr);
                spin_unlock_irqrestore(&lp->lock, flags);
                return;
        }
        skb->dev = dev;
        skb_put(skb, pkt_len);
        skb->protocol = htons(ETH_P_LOCALTALK);

        insb(ioaddr, skb->data, pkt_len);               /* Eat the Data */

        if(lp->board==DAYNA)
                outb(1, ioaddr+DAYNA_INT_CARD);         /* Interrupt the card */

        spin_unlock_irqrestore(&lp->lock, flags);  /* Restore interrupts. */

        /* Check for bad response length */
        if(pkt_len < 0 || pkt_len > MAX_LLAP_SIZE)
        {
		printk(KERN_WARNING "%s: Bad packet length of %d bytes.\n",
			dev->name, pkt_len);
                lp->stats.tx_errors++;
                dev_kfree_skb_any(skb);
                return;
        }

        /* Set nodeid and then get out. */
        if(rsp_type == LAP_INIT_RSP)
        {	/* Nodeid taken from received packet. */
                lp->node_acquire = skb->data[0];
                dev_kfree_skb_any(skb);
                return;
        }

        /* One last check to make sure we have a good packet. */
        if(rsp_type != LAP_RESPONSE)
        {
                printk(KERN_WARNING "%s: Bad packet type %d.\n", dev->name, rsp_type);
                lp->stats.tx_errors++;
                dev_kfree_skb_any(skb);
                return;
        }

        skb->mac.raw    = skb->data;    /* Point to entire packet. */
        skb_pull(skb,3);
        skb->h.raw      = skb->data;    /* Point to data (Skip header). */

        /* Update the counters. */
        lp->stats.rx_packets++;
        lp->stats.rx_bytes += skb->len;

        /* Send packet to a higher place. */
        netif_rx(skb);
	dev->last_rx = jiffies;
}

static void cops_timeout(struct net_device *dev)
{
        struct cops_local *lp = netdev_priv(dev);
        int ioaddr = dev->base_addr;

	lp->stats.tx_errors++;
        if(lp->board==TANGENT)
        {
		if((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
               		printk(KERN_WARNING "%s: No TX complete interrupt.\n", dev->name);
	}
	printk(KERN_WARNING "%s: Transmit timed out.\n", dev->name);
	cops_jumpstart(dev);	/* Restart the card. */
	dev->trans_start = jiffies;
	netif_wake_queue(dev);
}

/*
 *	Make the card transmit a LocalTalk packet.
 */

static int cops_send_packet(struct sk_buff *skb, struct net_device *dev)
{
        struct cops_local *lp = netdev_priv(dev);
        int ioaddr = dev->base_addr;
        unsigned long flags;

        /*
         * Block a timer-based transmit from overlapping.
	 */

	netif_stop_queue(dev);

	spin_lock_irqsave(&lp->lock, flags);
	if(lp->board == DAYNA)	 /* Wait for adapter transmit buffer. */
		while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0)
			cpu_relax();
	if(lp->board == TANGENT) /* Wait for adapter transmit buffer. */
		while((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
			cpu_relax();

	/* Output IO length. */
	outb(skb->len, ioaddr);
	if(lp->board == DAYNA)
               	outb(skb->len >> 8, ioaddr);
	else
		outb((skb->len >> 8)&0x0FF, ioaddr);

	/* Output IO code. */
	outb(LAP_WRITE, ioaddr);

	if(lp->board == DAYNA)	/* Check the transmit buffer again. */
        	while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0);

	outsb(ioaddr, skb->data, skb->len);	/* Send out the data. */

	if(lp->board==DAYNA)	/* Dayna requires you kick the card */
		outb(1, ioaddr+DAYNA_INT_CARD);

	spin_unlock_irqrestore(&lp->lock, flags);	/* Restore interrupts. */

	/* Done sending packet, update counters and cleanup. */
	lp->stats.tx_packets++;
	lp->stats.tx_bytes += skb->len;
	dev->trans_start = jiffies;
	dev_kfree_skb (skb);
        return 0;
}

/*
 *	Dummy function to keep the Appletalk layer happy.
 */

static void set_multicast_list(struct net_device *dev)
{
        if(cops_debug >= 3)
		printk("%s: set_multicast_list executed\n", dev->name);
}

/*
 *      Another Dummy function to keep the Appletalk layer happy.
 */

static int cops_hard_header(struct sk_buff *skb, struct net_device *dev,
			    unsigned short type, void *daddr, void *saddr,
			    unsigned len)
{
        if(cops_debug >= 3)
                printk("%s: cops_hard_header executed. Wow!\n", dev->name);
        return 0;
}

/*
 *      System ioctls for the COPS LocalTalk card.
 */

static int cops_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
        struct cops_local *lp = netdev_priv(dev);
        struct sockaddr_at *sa = (struct sockaddr_at *)&ifr->ifr_addr;
        struct atalk_addr *aa = (struct atalk_addr *)&lp->node_addr;

        switch(cmd)
        {
                case SIOCSIFADDR:
			/* Get and set the nodeid and network # atalkd wants. */
			cops_nodeid(dev, sa->sat_addr.s_node);
			aa->s_net               = sa->sat_addr.s_net;
                        aa->s_node              = lp->node_acquire;

			/* Set broardcast address. */
                        dev->broadcast[0]       = 0xFF;

			/* Set hardware address. */
                        dev->dev_addr[0]        = aa->s_node;
                        dev->addr_len           = 1;
                        return 0;

                case SIOCGIFADDR:
                        sa->sat_addr.s_net      = aa->s_net;
                        sa->sat_addr.s_node     = aa->s_node;
                        return 0;

                default:
                        return -EOPNOTSUPP;
        }
}

/*
 *	The inverse routine to cops_open().
 */

static int cops_close(struct net_device *dev)
{
	struct cops_local *lp = netdev_priv(dev);

	/* If we were running polled, yank the timer.
	 */
	if(lp->board==TANGENT && dev->irq==0)
		del_timer(&cops_timer);

	netif_stop_queue(dev);
        return 0;
}

/*
 *      Get the current statistics.
 *      This may be called with the card open or closed.
 */
static struct net_device_stats *cops_get_stats(struct net_device *dev)
{
        struct cops_local *lp = netdev_priv(dev);
        return &lp->stats;
}

#ifdef MODULE
static struct net_device *cops_dev;

MODULE_LICENSE("GPL");
module_param(io, int, 0);
module_param(irq, int, 0);
module_param(board_type, int, 0);

int init_module(void)
{
	if (io == 0)
		printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n",
			cardname);
	cops_dev = cops_probe(-1);
	if (IS_ERR(cops_dev))
		return PTR_ERR(cops_dev);
        return 0;
}

void cleanup_module(void)
{
	unregister_netdev(cops_dev);
	cleanup_card(cops_dev);
	free_netdev(cops_dev);
}
#endif /* MODULE */

/*
 * Local variables:
 *  compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -c cops.c"
 *  c-basic-offset: 4
 *  c-file-offsets: ((substatement-open . 0))
 * End:
 */


text:
Home / Press Room / 2019 News
John W. Walz Named Recipient of 2019 IEEE Computer Society Richard E. Merwin Award
LOS ALAMITOS, Calif., 12 February 2019 – IEEE Computer Society (IEEE CS) 2012 President and Senior IEEE Member John W. Walz has been selected to receive the 2019 Richard E. Merwin Award for Distinguished Service.
Walz was recognized "for service to the Computer Society with dedication and strong leadership aligned with a visionary strategic plan."
Walz retired from Lucent Technologies/AT&T with more than 20 years of management/coaching experience, covering positions in hardware and software engineering, quality planning and auditing, standards development and implementation, and strategic planning.
"I am deeply honored to be recognized with this important service award," said Walz. "The prior awardees are leaders who moved the Society ahead and also mentored me to recognize the diverse talent in our volunteers. I have enjoyed partnering with others to make many contributions to strengthen the Society and thus benefit the Institute."
As a longtime volunteer leader, Walz has worked with many talented individuals, including the current and past eleven IEEE presidents, and the current and past eight TAB VPs. As senior volunteer leader, past chair of two board committees, former IEEE CS president, and technical manager for AT&T's Lucent Technologies for 25 years, he developed the ability to understand, recruit, and position volunteer talent for best impact.
Walz has co-authored three books covering the use of IEEE Software Engineering Standards to support CMMI, ISO 9001, and Lean Six Sigma. He is also a contributor to IEEE CS ReadyNotes, industry webinar programs, and draft standards IEEE 90003:2017 and IEEE 730:2015.
His past leadership positions in national and international industry and professional organizations include U.S. Technical Advisory Group on Quality Management ISO 9001 and Risk Management ISO 31000; American Society for Quality (ASQ) Electronics and Communications Division and its Sarbanes-Oxley Forum; the Quality Excellence for Suppliers of Telecommunications Forum, which developed and deployed TL 9000 Quality Management System requirements and measurements; and the Information Integrity Coalition.
Walz received his BS and MS in electrical engineering from Ohio State University.
The Merwin Award is given to individuals for outstanding volunteer service to the profession at large, including significant service to the Computer Society. The Merwin Award is the IEEE-CS's highest level volunteer service award, and consists of a bronze medal and a $5,000 honorarium.
The award will be presented at a location to be determined.
Further information about the award, including past participants, may be found here.
About IEEE Computer Society
The IEEE Computer Society is the world's home for computer science, engineering, and technology. A global leader in providing access to computer science research, analysis, and information, the IEEE Computer Society offers a comprehensive array of unmatched products, services, and opportunities for individuals at all stages of their professional career. Known as the premier organization that empowers the people who drive technology, its unparalleled resources include membership, international conferences, peer-reviewed publications, a unique digital library, standards, and training programs. Visit www.computer.org for more information.

redpajama_set_name: RedPajamaCommonCrawl


text:
EDITORIAL: Autistic teen still waiting for justice
AsburyPark
Back in the dead of winter, Christopher Tilton, 20, and Nicholas Formica, 21, were charged with endangering the welfare of a mentally incompetent person by allegedly offering $20 and two packs of cigarettes to Parker Drake, a 19-year-old Howell man with autism, if he would jump off the Manasquan jetty into the freezing Atlantic Ocean.
It was not only a stupid and cruel prank, made worse by their posting a video of it on social media. The prank could have cost Drake his life. But his search for justice goes on. This week, defense attorneys for Tilton and Formica, both of Howell, asked the judge to enforce a plea bargain that had been negotiated by attorneys on both sides. But Drake and his mother, Christine Marshall, after initially agreeing to the deal, changed their minds and now want the case to go to trial. Manasquan Municipal Judge Paul J. Caportorto should honor their request.
It was hard enough for Parker's mother to bring action against the two men in the first place. When she first sought to press charges on behalf of her son, she was told by authorities that the behavior of Tilton and Formica was not a crime under New Jersey law. So, she signed complaints charging them with a disorderly persons offense, punishable by up to six months in jail.
Plea deal for pair in autistic teen's plunge?
Unfortunately, New Jersey law does not require that victims of crimes approve plea bargains. So now Caportorto must decide whether to enforce what attorneys claim was an agreed upon resolution of the case.
Marshall was understandably upset that neither she nor her son were given an opportunity to address the judge at this week's hearing: "I just feel that we should have a right to speak," Marshall said outside the courtroom. "They've never heard Parker speak. Isn't the judge interested in why I'm taking the plea back? Isn't it important why I'm changing my mind?"
We think it is. The court should be interested as well. Parker and his mother have been whipsawed enough by the courts. Their voices need to be heard.
EDITORIAL: Get justice for Parker
News of Drake's ordeal prompted several state lawmakers to propose legislation that would make it a crime for anyone who would endanger the welfare of a developmentally disabled individual.
A bill sponsored by Senate President Steve Sweeney, D-Gloucester, and Sen. Robert Singer, R-Ocean, was passed by the Senate in June. No action has been taken in the Assembly. When the Legislature reconvenes after the November election, it must act on behalf of the developmentally disabled, ensuring that in the future they will be able to seek justice more easily and with more appropriate penalties.
Meanwhile, Judge Caportorto should give Drake his day in court.
Pair encouraged autistic man to plunge in icy ocean


At Karni we aim to bring out the best in the students by pushing their potential and imbibing the ethical values along with helping them in achieving the academic success. Admission process at Karni International is transparent. We take this opportunity to introduce you to our program and process.
2.	Fill out the application form for registration.
3.	Submit the application form along with required documents.
4. Go through the selection process.
5.	Pay the applicable fees, once the admission* is confirmed.
* All rights regarding admissions are reserved with the school management.
*NOTE: All parents are politely requested to note that all rights regarding admissions are reserved with the school management. And the Karni International school has the right to suspend or terminate the enrolment of a student at any time.
Registration forms can be obtained from the school office. Forms need to be fully completed and submitted within 3 days from the date of purchase.


text:
Flamenco star Rosalía
Spanish artist Rosalia takes fifth place in the BBC Music Sound of 2019 list
Flamenco music has never troubled the UK charts — but that looks set to change with the arrival of Rosalía.
The 25-year-old is turning flamenco on its head by tethering its vocal melismas and palmas (hand clapping) to the sounds and attitude of hip-hop.
It's earned the singer fifth place in the BBC Music Sound of 2019, which tips acts for success in the next 12 months.
Born Rosalía Vila Tobella in Sant Esteve Sesrovires, Spain, she's already a big star at home.
Her 2017 debut Los Ángeles spent 67 weeks in the Spanish album chart.
Its fusion of old and new world traditions «revolutionised flamenco», according to Spain's La Vanguardia, while the striking video for De Plata, in which Rosalía performs intricate flamenco moves against a series of Instagram-friendly backdrops, racked up four million view on YouTube.
She soon caught the eye of Pharrell Williams, who invited her to record with him in LA, and Oscar-winning writer-director Pedro Almodóvar, who cast her alongside Penélope Cruz in his next film, Dolor y Gloria.
But it was her second album, El Mal Querer, that brought the singer to a global audience.
A modern retelling of the 13th Century novel Flamenca, it started life as Rosalía's graduate thesis for Barcelona's Catalonia School of Music, where she studied flamenco (they accept one student per year) and music production.
The album earned her five nominations at the Latin Grammys, where the ominous, bass-busting single Malamente won best alternative song and best urban track.
With Latin pop continuing to rise, and a major label fighting her corner, 2019 could be a breakthrough year for the Catalan star.
Hi Rosalía! Congratulations on making it into the Sound of 2019!
Thank you so much! I'm really happy. I've discovered a lot of music by listening to the BBC — but it was a big surprise that I could have a space on this list, you know?
How did you first get interested in music?
I always had a connection with music. Nobody in my family played music professionally but, as a little kid, I used to sing and dance all the time. Whatever I heard on the television or the radio, I'd just repeat it. I don't know why.
Where was home?
I grew up in Sant Esteve Sesrovires, a small village near Barcelona. My house was near the countryside, so there was a lot of nature, and at the same time my village is surrounded by factories. That conditioned me a little bit.
«She could be the Rihanna of flamenco,» the director of Spain's Sonar Festival told the New York Times
I can hear that in your music — there are a lot of acoustic sounds but you also sample a revving motorcycle on De Aquí No Sales.
Exactly. I always liked motorcycles and cars when I was a kid. There's never a sound that I think I can't use in my music.
Did you always approach songwriting like that?
I got obsessed with flamenco when I was 13 and flamenco is my foundation, but I'm always trying to understand la musica tonal — other cultures, other music. I grew up with Tupac Shakur, but I also loved Wagner and Chopin.
So although I had a very acoustic sound when I first started singing flamenco, later I wanted to experiment with samples and beats, because I'm very connected with urban music.
Was it easy to combine the two?
It was very natural. I had it in my ear and in my mind — all those different sounds that are usually sin presentia [not in sympathy]. Like, in flamenco, nobody has ever felt those sounds could live in the same place at the same time. It's difficult to explain in English but I'm doing my best!
The star is booked to play festivals including Coachella and Primavera this year
The album title translates in English as Toxic Love. What inspired the story?
I had the title before anything else, during the last year of my university degree. I wanted to explore this bad love — las pasiones. You know, like domination, the dark side of love.
And I wanted to make a record where every song could be a chapter, almost so you could «read» the album. Like, when you hear the third song, maybe you hear it in a different way because you know what happened in chapter two. So I just started looking for references, digging through books to find traditional lyrics.
How did you discover Flamenca?
I found it completely at random. I was drinking coffee with a friend of mine, and he said, «Have you read this book?» and it blew my mind because the story was about a woman who falls in love with a man who proposes marriage — but then he gets super crazy jealous and imprisons her. I connected with that story so much that I felt I could compose the structure, the chapters, around this idea. It was perfect.
Was it a challenge to channel all that angst and vulnerability and aggression?
For me, it was interesting to write in a masculine voice or think in a feminine voice, just in particular for this story. I tried to find different ways to use my voice, I worked with a choir of young girls, and I worked these very aggressive flamenco singers. I wanted to find different ways to approach this flamenco inspiration and electronic sound but with voices always in the centre.
The melodies often have an Arabic feel. Is that common in flamenco?
Flamenco is connected with so many types of music. It has Jewish culture inside, Arabian culture inside, Russian culture inside, Spanish culture inside. It's linked to African music too, because African music has the " amalgama" rhythms you can find in flamenco. You can find everything in flamenco. That's why it's so beautiful.
Flamenco is very closely associated with dance, too. Are your performances as physically strenuous as they look?
I think so. For me, there's a connection: The more free my body is, the better my voice sounds.
I used to sing in Tablaos, these traditional places where they played this music and I used to watch how the dancers moved. I have always been attentive to all the detail. I also studied guitar — I'm not a flamenco guitar player because that's so difficult, but I've been studying for a long time just to understand the chords and the harmony.
Your videos both celebrate and deconstruct the cultural and religious symbols of Catalonia. Can we talk about that?
My parents are not religious, but my grandma was. She brought me to church some Sundays and I remember the music and the heaviness of the morality. When I use that imagery, I'm not trying to make an apology or criticism. It's about putting something on the table that's related to my experiences and my culture, and using visual metaphors so you can understand even harder or better my music.
There's a moment in Pienso En Tu Mira where you're performing in between two moving trucks. Every time I see it, I worry you're about to get run over.
I was worried about the same thing when we shot it! I just had to trust all of the crew and I survived it! But I love taking risks everywhere, from my music to my videos.
If you weren't as familiar with rising flamenco-pop icon Rosalía as the rest of the world, she made sure to let you know who she was at the 2019 MTV Video Music Awards. The Spanish singer-songwriter hit the stage on Monday night (August 26), stunning viewers with a flavorful and dynamic performance that included not one, not two, but three songs, including a team-up with Ozuna.
Rosalía's Powerhouse VMA Performance
At first, Rosalía's performance seemed minimalistic. In a robe under a spotlight, she began singing «A Ningún Hombre (Cap.11: Poder)» a cappella. But soon after, the 25-year-old songstress was interrupted by a powerful voice over the PA system. It was then that the beat began to pick up and dancers appeared onstage. Their first order of business? Removing Rosalía's robe to expose something a bit more suitable for the occasion: a black dress with glittery seams. On the back, her name spelled out in rhinestones.
As «Yo X Ti, Tu X Mi» began to play, the stage went full-on floral, setting the scene for a flirty duet with none other than Puerto Rican superstar Ozuna. But while the onstage chemistry between the two was undeniable, it was short-lived: Ozuna only joined Rosalía briefly, exiting the stage before she blew us away with a high-energy, powerhouse performance of «Aute Cuture.»
At this point, it's pretty clear why Rosalía was nominated in a whopping three categories, including Best New Artist, Best Choreography, and Best Latin. (In fact, at the time of this performance, she'd already accepted Best Latin with collaborator J Balvin.) Still, it's always satisfying when a performance has a strong finish. Fortunately, she did not disappoint. After making her way to the back of the stage with her dancers in tow, she struck a pose as strong as a matador. At that moment, her name lit up on the neon castle behind her. She's Rosalía… and don't you forget it.
Rosalía, flamenco, BBC, MTV, VMA
Sofía Vergara: the hottest Hispanic TV star
Barcelona: Flamenco Show at the Tablao in Las Ramblas
Giant star illuminates Barcelona skyline on inauguration of Sagrada Familia tower
Rosalía Latin Grammy 2022


text:
HOME | TORNOS+ | GREEN TRAVEL
Grey's Anatomy star Sarah Drew enchanted by Greek capital of Athens
Sarah Drew, an actress in Grey's Anatomy, at the Acropolis. Credit: Instagram/Sarah Drew
"Grey's Anatomy" star Sarah Drew, who has been vacationing in Greece with her family has clearly fallen in love with Athens, according to greekreporter.com.
"Good morning Greece. You are very pretty," she noted on Instagram as she opened the doors of her hotel's roof terrace overlooking the Acropolis on her first day in the Greek capital.
Drew, who played Dr. April Kepner in the ABC medical drama series, posted several photos of her stay in Athens. She was escorted by her husband, Peter Lanfer, a lecturer at UCLA, and her three children.
Her Instagram photos comprise a tourist guide to the Greek capital and its most visited ancient sites. Of course, a tour of the Acropolis and a photo at the Parthenon was top of the list.
1) EU Commission calls on six member states to apply nvironmental directives
2) Greece to transform "green" commercial shipping fleet with new fund
3) Irish writer claims tourism and development may be the end of Corfu island
4) Mexico's Yucatán State joins global Network of Sustainable Tourism Observatories
more articles on GREEN TRAVEL
Greek island of Naxos among top sustainable travel experiences


•In addition to mass advertisement and Internet advertisement, various initiatives such as digital promotion utilizing the Web, store front link event at the real store, regional revitalization related to regional creation and inbound measures were implemented. We respond widely to the marketing field in general, including proposals and measures for overall marketing that comprehensively combine such diverse solutions, support for product development, etc. To concretely index (define) the strategic goal of the firm, to plan, design and implement Japan's own brand survey to monitor the degree of achievement of brand indicators and competitive comparison over the years.
•Grasp the marketing issues, conduct various investigations and analysis, proposal of solutions and strategies, project direction for the companies, clients of public enterprises, finance industry and general consumer goods.