Esempio n. 1
0
static void
falcon_release_lock_if_possible( struct NCR5380_hostdata * hostdata )
{
	unsigned long flags;
		
	if (IS_A_TT()) return;
	
	local_irq_save(flags);

	if (falcon_got_lock &&
		!hostdata->disconnected_queue &&
		!hostdata->issue_queue &&
		!hostdata->connected) {

		if (falcon_dont_release) {
#if 0
			printk("WARNING: Lock release not allowed. Ignored\n");
#endif
			local_irq_restore(flags);
			return;
		}
		falcon_got_lock = 0;
		stdma_release();
		wake_up( &falcon_fairness_wait );
	}

	local_irq_restore(flags);
}
Esempio n. 2
0
/* currently unused */
static int slm_mode_select( int device, char *buffer, int len,
							int default_flag )

{	int			stat, rv;
	struct slm	*sip = &slm_info[device];
	
	stdma_lock( NULL, NULL );

	CMDSET_TARG_LUN( slmmselect_cmd, sip->target, sip->lun );
	slmmselect_cmd[5] = default_flag ? 0x80 : 0;
	if (!acsicmd_nodma( slmmselect_cmd, 0 )) {
		rv = SLMSTAT_ACSITO;
		goto the_end;
	}

	if (!default_flag) {
		unsigned char c = len;
		if (!acsi_extcmd( &c, 1 )) {
			rv = SLMSTAT_ACSITO;
			goto the_end;
		}
		if (!acsi_extcmd( buffer, len )) {
			rv = SLMSTAT_ACSITO;
			goto the_end;
		}
	}
	
	stat = acsi_getstatus();
	rv = (stat < 0 ? SLMSTAT_ACSITO : stat);

  the_end:
	ENABLE_IRQ();
	stdma_release();
	return( rv );
}
Esempio n. 3
0
static void falconide_release_lock(void)
{
	if (falconide_intr_lock == 0) {
;
		return;
	}
	falconide_intr_lock = 0;
	stdma_release();
}
Esempio n. 4
0
static int slm_get_pagesize( int device, int *w, int *h )

{	char	buf[256];
	int		stat;
	
	stat = slm_mode_sense( device, buf, 0 );
	ENABLE_IRQ();
	stdma_release();

	if (stat != SLMSTAT_OK)
		return( -EIO );

	*w = (buf[3] << 8) | buf[4];
	*h = (buf[1] << 8) | buf[2];
	return( 0 );
}
Esempio n. 5
0
static int slm_req_sense( int device )

{	int			stat, rv;
	struct slm *sip = &slm_info[device];
	
	stdma_lock( NULL, NULL );

	CMDSET_TARG_LUN( slmreqsense_cmd, sip->target, sip->lun );
	if (!acsicmd_nodma( slmreqsense_cmd, 0 ) ||
		(stat = acsi_getstatus()) < 0)
		rv = SLMSTAT_ACSITO;
	else
		rv = stat & 0x1f;

	ENABLE_IRQ();
	stdma_release();
	return( rv );
}
Esempio n. 6
0
/* The inverse routine to bionet_open().
 */
static int
bionet_close(struct net_device *dev) {
    struct net_local *lp = netdev_priv(dev);

    if (bionet_debug > 0)
        printk("bionet_close, open_time=%ld\n", lp->open_time);
    del_timer(&bionet_timer);
    stdma_lock(bionet_intr, NULL);

    set_status(0);
    lp->open_time = 0;

    dev->tbusy = 1;
    dev->start = 0;

    stdma_release();
    return 0;
}
Esempio n. 7
0
static int slm_mode_sense( int device, char *buffer, int abs_flag )

{	unsigned char	stat, len;
	int				rv = 0;
	struct slm		*sip = &slm_info[device];
	
	stdma_lock( NULL, NULL );

	CMDSET_TARG_LUN( slmmsense_cmd, sip->target, sip->lun );
	slmmsense_cmd[5] = abs_flag ? 0x80 : 0;
	if (!acsicmd_nodma( slmmsense_cmd, 0 )) {
		rv = SLMSTAT_ACSITO;
		goto the_end;
	}

	if (!acsi_extstatus( &stat, 1 )) {
		acsi_end_extstatus();
		rv = SLMSTAT_ACSITO;
		goto the_end;
	}
	
	if (!acsi_extstatus( &len, 1 )) {
		acsi_end_extstatus();
		rv = SLMSTAT_ACSITO;
		goto the_end;
	}
	buffer[0] = len;
	if (!acsi_extstatus( buffer+1, len )) {
		acsi_end_extstatus();
		rv = SLMSTAT_ACSITO;
		goto the_end;
	}
	
	acsi_end_extstatus();
	rv = stat & 0x1f;

  the_end:
	ENABLE_IRQ();
	stdma_release();
	return( rv );
}
Esempio n. 8
0
static void slm_interrupt(int irc, void *data, struct pt_regs *fp)

{	unsigned long	addr;
	int				stat;
	
	STOP_TIMER();
	addr = get_dma_addr();
	stat = acsi_getstatus();
	SLMError = (stat < 0)             ? SLMSTAT_ACSITO :
		       (addr < virt_to_phys(BufferP)) ? SLMSTAT_NOTALL :
									    stat;

	dma_wd.dma_mode_status = 0x80;
	MFPDELAY();
#ifdef DEBUG
	printk( "SLM: interrupt, addr=%#lx, error=%d\n", addr, SLMError );
#endif

	wake_up( &print_wait );
	stdma_release();
	ENABLE_IRQ();
}
Esempio n. 9
0
/* Open/initialize the board.  This is called (in the current kernel)
   sometime after booting when the 'ifconfig' program is run.

   This routine should set everything up anew at each open, even
   registers that "should" only need to be set once at boot, so that
   there is non-reboot way to recover if something goes wrong.
 */
static int
bionet_open(struct net_device *dev) {
    struct net_local *lp = netdev_priv(dev);

    if (bionet_debug > 0)
        printk("bionet_open\n");
    stdma_lock(bionet_intr, NULL);

    /* Reset the hardware here.
     */
    set_status(4);
    lp->open_time = 0;	/*jiffies*/
    lp->poll_time = MAX_POLL_TIME;

    dev->tbusy = 0;
    dev->interrupt = 0;
    dev->start = 1;

    stdma_release();
    bionet_timer.data = (long)dev;
    bionet_timer.expires = jiffies + lp->poll_time;
    add_timer(&bionet_timer);
    return 0;
}
Esempio n. 10
0
/* We have a good packet(s), get it/them out of the buffers.
 */
static void
bionet_poll_rx(struct net_device *dev) {
    struct net_local *lp = netdev_priv(dev);
    int boguscount = 10;
    int pkt_len, status;
    unsigned long flags;

    local_irq_save(flags);
    /* ++roman: Take care at locking the ST-DMA... This must be done with ints
     * off, since otherwise an int could slip in between the question and the
     * locking itself, and then we'd go to sleep... And locking itself is
     * necessary to keep the floppy_change timer from working with ST-DMA
     * registers. */
    if (stdma_islocked()) {
        local_irq_restore(flags);
        return;
    }
    stdma_lock(bionet_intr, NULL);
    DISABLE_IRQ();
    local_irq_restore(flags);

    if( lp->poll_time < MAX_POLL_TIME ) lp->poll_time++;

    while(boguscount--) {
        status = get_frame((unsigned long)phys_nic_packet, 0);

        if( status == 0 ) break;

        /* Good packet... */

        dma_cache_maintenance((unsigned long)phys_nic_packet, 1520, 0);

        pkt_len = (nic_packet->l_hi << 8) | nic_packet->l_lo;

        lp->poll_time = bionet_min_poll_time;    /* fast poll */
        if( pkt_len >= 60 && pkt_len <= 1520 ) {
            /*	^^^^ war 1514  KHL */
            /* Malloc up new buffer.
             */
            struct sk_buff *skb = dev_alloc_skb( pkt_len + 2 );
            if (skb == NULL) {
                printk("%s: Memory squeeze, dropping packet.\n",
                       dev->name);
                lp->stats.rx_dropped++;
                break;
            }

            skb->dev = dev;
            skb_reserve( skb, 2 );		/* 16 Byte align  */
            skb_put( skb, pkt_len );	/* make room */

            /* 'skb->data' points to the start of sk_buff data area.
             */
            memcpy(skb->data, nic_packet->buffer, pkt_len);
            skb->protocol = eth_type_trans( skb, dev );
            netif_rx(skb);
            dev->last_rx = jiffies;
            lp->stats.rx_packets++;
            lp->stats.rx_bytes+=pkt_len;

            /* If any worth-while packets have been received, dev_rint()
               has done a mark_bh(INET_BH) for us and will work on them
               when we get to the bottom-half routine.
             */

            if (bionet_debug >1) {
                u_char *data = nic_packet->buffer, *p;
                int i;

                printk( "%s: RX pkt type 0x%4x from ", dev->name,
                        ((u_short *)data)[6]);


                for( p = &data[6], i = 0; i < 6; i++ )
                    printk("%02x%s", *p++,i != 5 ? ":" : "" );
                printk(" to ");
                for( p = data, i = 0; i < 6; i++ )
                    printk("%02x%s", *p++,i != 5 ? ":" : "" "\n" );

                printk( "%s: ", dev->name );
                printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x"
                       " %02x%02x%02x%02x len %d\n",
                       data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19],
                       data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27],
                       data[28], data[29], data[30], data[31], data[32], data[33],
                       pkt_len );
            }
        }
        else {
            printk(" Packet has wrong length: %04d bytes\n", pkt_len);
            lp->stats.rx_errors++;
        }
    }
    stdma_release();
    ENABLE_IRQ();
    return;
}
Esempio n. 11
0
static int
bionet_send_packet(struct sk_buff *skb, struct net_device *dev) {
    struct net_local *lp = netdev_priv(dev);
    unsigned long flags;

    /* Block a timer-based transmit from overlapping.  This could better be
     * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
     */
    local_irq_save(flags);

    if (stdma_islocked()) {
        local_irq_restore(flags);
        lp->stats.tx_errors++;
    }
    else {
        int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
        unsigned long buf = virt_to_phys(skb->data);
        int stat;

        stdma_lock(bionet_intr, NULL);
        local_irq_restore(flags);
        if( !STRAM_ADDR(buf+length-1) ) {
            memcpy(nic_packet->buffer, skb->data, length);
            buf = (unsigned long)&((struct nic_pkt_s *)phys_nic_packet)->buffer;
        }

        if (bionet_debug >1) {
            u_char *data = nic_packet->buffer, *p;
            int i;

            printk( "%s: TX pkt type 0x%4x from ", dev->name,
                    ((u_short *)data)[6]);

            for( p = &data[6], i = 0; i < 6; i++ )
                printk("%02x%s", *p++,i != 5 ? ":" : "" );
            printk(" to ");

            for( p = data, i = 0; i < 6; i++ )
                printk("%02x%s", *p++,i != 5 ? ":" : "" "\n" );

            printk( "%s: ", dev->name );
            printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x"
                   " %02x%02x%02x%02x len %d\n",
                   data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19],
                   data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27],
                   data[28], data[29], data[30], data[31], data[32], data[33],
                   length );
        }
        dma_cache_maintenance(buf, length, 1);

        stat = hardware_send_packet(buf, length);
        ENABLE_IRQ();
        stdma_release();

        dev->trans_start = jiffies;
        dev->tbusy	 = 0;
        lp->stats.tx_packets++;
        lp->stats.tx_bytes+=length;
    }
    dev_kfree_skb(skb);

    return 0;
}
Esempio n. 12
0
/* Check for a network adaptor of this type, and return '0' if one exists.
 */
struct net_device * __init bionet_probe(int unit)
{
    struct net_device *dev;
    unsigned char station_addr[6];
    static unsigned version_printed;
    static int no_more_found;	/* avoid "Probing for..." printed 4 times */
    int i;
    int err;

    if (!MACH_IS_ATARI || no_more_found)
        return ERR_PTR(-ENODEV);

    dev = alloc_etherdev(sizeof(struct net_local));
    if (!dev)
        return ERR_PTR(-ENOMEM);
    if (unit >= 0) {
        sprintf(dev->name, "eth%d", unit);
        netdev_boot_setup_check(dev);
    }
    SET_MODULE_OWNER(dev);

    printk("Probing for BioNet 100 Adapter...\n");

    stdma_lock(bionet_intr, NULL);
    i = get_status(station_addr);	/* Read the station address PROM.  */
    ENABLE_IRQ();
    stdma_release();

    /* Check the first three octets of the S.A. for the manufactor's code.
     */

    if( i < 0
            ||  station_addr[0] != 'B'
            ||  station_addr[1] != 'I'
            ||  station_addr[2] != 'O' ) {
        no_more_found = 1;
        printk( "No BioNet 100 found.\n" );
        free_netdev(dev);
        return ERR_PTR(-ENODEV);
    }

    if (bionet_debug > 0 && version_printed++ == 0)
        printk(version);

    printk("%s: %s found, eth-addr: %02x-%02x-%02x:%02x-%02x-%02x.\n",
           dev->name, "BioNet 100",
           station_addr[0], station_addr[1], station_addr[2],
           station_addr[3], station_addr[4], station_addr[5]);

    /* Initialize the device structure. */

    nic_packet = (struct nic_pkt_s *)acsi_buffer;
    phys_nic_packet = (unsigned char *)phys_acsi_buffer;
    if (bionet_debug > 0) {
        printk("nic_packet at 0x%p, phys at 0x%p\n",
               nic_packet, phys_nic_packet );
    }

    dev->open		= bionet_open;
    dev->stop		= bionet_close;
    dev->hard_start_xmit	= bionet_send_packet;
    dev->get_stats		= net_get_stats;

    /* Fill in the fields of the device structure with ethernet-generic
     * values. This should be in a common file instead of per-driver.
     */

    for (i = 0; i < ETH_ALEN; i++) {
#if 0
        dev->broadcast[i] = 0xff;
#endif
        dev->dev_addr[i]  = station_addr[i];
    }
    err = register_netdev(dev);
    if (!err)
        return dev;
    free_netdev(dev);
    return ERR_PTR(err);
}