Esempio n. 1
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. 2
0
static void falcon_get_lock( void )
{
	unsigned long flags;

	if (IS_A_TT()) return;

	local_irq_save(flags);

	while( !in_interrupt() && falcon_got_lock && stdma_others_waiting() )
		sleep_on( &falcon_fairness_wait );

	while (!falcon_got_lock) {
		if (in_interrupt())
			panic( "Falcon SCSI hasn't ST-DMA lock in interrupt" );
		if (!falcon_trying_lock) {
			falcon_trying_lock = 1;
			stdma_lock(scsi_falcon_intr, NULL);
			falcon_got_lock = 1;
			falcon_trying_lock = 0;
			wake_up( &falcon_try_wait );
		}
		else {
			sleep_on( &falcon_try_wait );
		}
	}	

	local_irq_restore(flags);
	if (!falcon_got_lock)
		panic("Falcon SCSI: someone stole the lock :-(\n");
}
Esempio n. 3
0
static void falcon_get_lock( void )
{
	unsigned long	oldflags;

	if (IS_A_TT()) return;

	save_flags(oldflags);
	cli();

	while( intr_count == 0 && falcon_got_lock && stdma_others_waiting() )
		sleep_on( &falcon_fairness_wait );

	while (!falcon_got_lock) {
		if (intr_count > 0)
			panic( "Falcon SCSI hasn't ST-DMA lock in interrupt" );
		if (!falcon_trying_lock) {
			falcon_trying_lock = 1;
			stdma_lock(scsi_falcon_intr, NULL);
			falcon_got_lock = 1;
			falcon_trying_lock = 0;
			wake_up( &falcon_try_wait );
		}
		else {
			sleep_on( &falcon_try_wait );
		}
	}	

	restore_flags(oldflags);
	if (!falcon_got_lock)
		panic("Falcon SCSI: someone stole the lock :-(\n");
}
Esempio n. 4
0
static void falconide_get_lock(irq_handler_t handler, void *data)
{
	if (falconide_intr_lock == 0) {
		if (in_interrupt() > 0)
			panic("Falcon IDE hasn't ST-DMA lock in interrupt");
		stdma_lock(handler, data);
		falconide_intr_lock = 1;
	}
}
Esempio n. 5
0
static void start_print( int device )

{	struct slm *sip = &slm_info[device];
	unsigned char	*cmd;
	unsigned long	paddr;
	int				i;
	
	stdma_lock( slm_interrupt, NULL );

	CMDSET_TARG_LUN( slmprint_cmd, sip->target, sip->lun );
	cmd = slmprint_cmd;
	paddr = virt_to_phys( SLMBuffer );
	dma_cache_maintenance( paddr, virt_to_phys(BufferP)-paddr, 1 );
	DISABLE_IRQ();

	/* Low on A1 */
	dma_wd.dma_mode_status = 0x88;
	MFPDELAY();

	/* send the command bytes except the last */
	for( i = 0; i < 5; ++i ) {
		DMA_LONG_WRITE( *cmd++, 0x8a );
		udelay(20);
		if (!acsi_wait_for_IRQ( HZ/2 )) {
			SLMError = 1;
			return; /* timeout */
		}
	}
	/* last command byte */
	DMA_LONG_WRITE( *cmd++, 0x82 );
	MFPDELAY();
	/* set DMA address */
	set_dma_addr( paddr );
	/* program DMA for write and select sector counter reg */
	dma_wd.dma_mode_status = 0x192;
	MFPDELAY();
	/* program for 255*512 bytes and start DMA */
	DMA_LONG_WRITE( SLM_DMA_AMOUNT, 0x112 );

#ifndef SLM_CONT_CNT_REPROG
	SLMCurAddr = paddr;
	SLMEndAddr = paddr + SLMSliceSize + SLM_DMA_INT_OFFSET;
#endif
	START_TIMER( DMA_STARTUP_TIME + DMA_TIME_FOR( SLMSliceSize ));
#if !defined(SLM_CONT_CNT_REPROG) && defined(DEBUG)
	printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n",
			SLMCurAddr, SLMEndAddr, DMA_TIME_FOR( SLMSliceSize ) );
#endif
	
	ENABLE_IRQ();
}
Esempio n. 6
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. 7
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. 8
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. 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);
}