Example #1
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();
}
Example #2
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;
}
Example #3
0
unsigned long atari_scsi_dma_setup( struct Scsi_Host *instance, void *data,
				   unsigned long count, int dir )
{
	unsigned long addr = virt_to_phys( data );

	DMA_PRINTK("scsi%d: setting up dma, data = %p, phys = %lx, count = %ld, "
		   "dir = %d\n", instance->host_no, data, addr, count, dir);

	if (!IS_A_TT() && !STRAM_ADDR(addr)) {
		/* If we have a non-DMAable address on a Falcon, use the dribble
		 * buffer; 'orig_addr' != 0 in the read case tells the interrupt
		 * handler to copy data from the dribble buffer to the originally
		 * wanted address.
		 */
		if (dir)
			memcpy( atari_dma_buffer, data, count );
		else
			atari_dma_orig_addr = data;
		addr = atari_dma_phys_buffer;
	}
	
	atari_dma_startaddr = addr;	/* Needed for calculating residual later. */
  
	/* Cache cleanup stuff: On writes, push any dirty cache out before sending
	 * it to the peripheral. (Must be done before DMA setup, since at least
	 * the ST-DMA begins to fill internal buffers right after setup. For
	 * reads, invalidate any cache, may be altered after DMA without CPU
	 * knowledge.
	 * 
	 * ++roman: For the Medusa, there's no need at all for that cache stuff,
	 * because the hardware does bus snooping (fine!).
	 */
	dma_cache_maintenance( addr, count, dir );

	if (count == 0)
		printk(KERN_NOTICE "SCSI warning: DMA programmed for 0 bytes !\n");

	if (IS_A_TT()) {
		tt_scsi_dma.dma_ctrl = dir;
		SCSI_DMA_WRITE_P( dma_addr, addr );
		SCSI_DMA_WRITE_P( dma_cnt, count );
		tt_scsi_dma.dma_ctrl = dir | 2;
	}
	else { /* ! IS_A_TT */
  
		/* set address */
		SCSI_DMA_SETADR( addr );

		/* toggle direction bit to clear FIFO and set DMA direction */
		dir <<= 8;
		st_dma.dma_mode_status = 0x90 | dir;
		st_dma.dma_mode_status = 0x90 | (dir ^ 0x100);
		st_dma.dma_mode_status = 0x90 | dir;
		udelay(40);
		/* On writes, round up the transfer length to the next multiple of 512
		 * (see also comment at atari_dma_xfer_len()). */
		st_dma.fdc_acces_seccount = (count + (dir ? 511 : 0)) >> 9;
		udelay(40);
		st_dma.dma_mode_status = 0x10 | dir;
		udelay(40);
		/* need not restore value of dir, only boolean value is tested */
		atari_dma_active = 1;
	}

	return( count );
}
Example #4
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;
}