Ejemplo n.º 1
0
/* Request needed resources */
static int znet_request_resources (struct net_device *dev)
{
	struct znet_private *znet = netdev_priv(dev);

	if (request_irq (dev->irq, znet_interrupt, 0, "ZNet", dev))
		goto failed;
	if (request_dma (znet->rx_dma, "ZNet rx"))
		goto free_irq;
	if (request_dma (znet->tx_dma, "ZNet tx"))
		goto free_rx_dma;
	if (!request_region (znet->sia_base, znet->sia_size, "ZNet SIA"))
		goto free_tx_dma;
	if (!request_region (dev->base_addr, znet->io_size, "ZNet I/O"))
		goto free_sia;

	return 0;				/* Happy ! */

 free_sia:
	release_region (znet->sia_base, znet->sia_size);
 free_tx_dma:
	free_dma (znet->tx_dma);
 free_rx_dma:
	free_dma (znet->rx_dma);
 free_irq:
	free_irq (dev->irq, dev);
 failed:
	return -1;
}
Ejemplo n.º 2
0
static int LOCOMX_close(struct net_device *dev)
{
	struct comx_channel *ch = netdev_priv(dev);
	struct locomx_data *hw = ch->HW_privdata;
	struct proc_dir_entry *procfile = ch->procdir->subdir;

	hw->board.chanA.rx_function=z8530_null_rx;
	netif_stop_queue(dev);
	z8530_sync_dma_close(dev, &hw->board.chanA);

	z8530_shutdown(&hw->board);

	del_timer(&hw->status_timer);
	free_dma(RX_DMA);
	free_dma(TX_DMA);
	free_irq(dev->irq,&hw->board);
	release_region(dev->base_addr,8);

	for (; procfile ; procfile = procfile->next) {
		if (strcmp(procfile->name, FILENAME_IO) == 0 ||
		    strcmp(procfile->name, FILENAME_IRQ) == 0) {
			procfile->mode = S_IFREG |  0644;
		}
	}

	ch->init_status &= ~HW_OPEN;
	return 0;
}
Ejemplo n.º 3
0
Archivo: iobuf.c Proyecto: 42wim/ipxe
/**
 * Free I/O buffer
 *
 * @v iobuf	I/O buffer
 */
void free_iob ( struct io_buffer *iobuf ) {
	size_t len;

	/* Allow free_iob(NULL) to be valid */
	if ( ! iobuf )
		return;

	/* Sanity checks */
	assert ( iobuf->head <= iobuf->data );
	assert ( iobuf->data <= iobuf->tail );
	assert ( iobuf->tail <= iobuf->end );

	/* Free buffer */
	len = ( iobuf->end - iobuf->head );
	if ( iobuf->end == iobuf ) {

		/* Descriptor is inline */
		free_dma ( iobuf->head, ( len + sizeof ( *iobuf ) ) );

	} else {

		/* Descriptor is detached */
		free_dma ( iobuf->head, len );
		free ( iobuf );
	}
}
Ejemplo n.º 4
0
static int snd_gus_free(struct snd_gus_card *gus)
{
	if (gus->gf1.res_port2 == NULL)
		goto __hw_end;
#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
	if (gus->seq_dev) {
		snd_device_free(gus->card, gus->seq_dev);
		gus->seq_dev = NULL;
	}
#endif
	snd_gf1_stop(gus);
	snd_gus_init_dma_irq(gus, 0);
      __hw_end:
	release_and_free_resource(gus->gf1.res_port1);
	release_and_free_resource(gus->gf1.res_port2);
	if (gus->gf1.irq >= 0)
		free_irq(gus->gf1.irq, (void *) gus);
	if (gus->gf1.dma1 >= 0) {
		disable_dma(gus->gf1.dma1);
		free_dma(gus->gf1.dma1);
	}
	if (!gus->equal_dma && gus->gf1.dma2 >= 0) {
		disable_dma(gus->gf1.dma2);
		free_dma(gus->gf1.dma2);
	}
	kfree(gus);
	return 0;
}
Ejemplo n.º 5
0
int __init bf561_coreb_init(void)
{
	struct proc_dir_entry *proc_entry;
	init_waitqueue_head(&coreb_dma_wait);

	/* Request the core memory regions for Core B */
	if (request_mem_region(0xff600000, 0x4000,
		"Core B - Instruction SRAM") == NULL)
		goto exit;

	if (request_mem_region(0xFF610000, 0x4000, 
		"Core B - Instruction SRAM") == NULL)
		goto release_instruction_a_sram;

	if (request_mem_region(0xFF500000, 0x8000,
		"Core B - Data Bank B SRAM") == NULL)
		goto release_instruction_b_sram;

	if (request_mem_region(0xff400000, 0x8000,
		"Core B - Data Bank A SRAM") == NULL)
		goto release_data_b_sram;

	if (request_dma(CH_MEM_STREAM2_DEST, "Core B - DMA Destination") < 0)
		goto release_data_a_sram;

	if (request_dma(CH_MEM_STREAM2_SRC, "Core B - DMA Source") < 0)
		goto release_dma_dest;

	set_dma_callback(CH_MEM_STREAM2_DEST, coreb_dma_interrupt, NULL);

	misc_register(&coreb_dev);

	printk(KERN_INFO "Core B: Initializing /proc\n");
	coreb_proc_entry = create_proc_entry("coreb", 0, NULL);
	if (coreb_proc_entry)
	{
		coreb_proc_entry->owner = THIS_MODULE;
		coreb_proc_entry->read_proc = coreb_read_status;
	} else {
		printk(KERN_ERR "Core B: Unable to register /proc/coreb\n");
		goto release_dma_src;
	}
	printk(KERN_INFO "BF561 Core B driver %s initialized.\n", MODULE_VER);
	return 0;

release_dma_src:
	free_dma(CH_MEM_STREAM2_SRC);
release_dma_dest:
	free_dma(CH_MEM_STREAM2_DEST);
release_data_a_sram:
	release_mem_region(0xff400000, 0x8000);
release_data_b_sram:
	release_mem_region(0xff500000, 0x8000);
release_instruction_b_sram:
	release_mem_region(0xff610000, 0x4000);
release_instruction_a_sram:
	release_mem_region(0xff600000, 0x4000);
exit:
	return -ENOMEM;
}
Ejemplo n.º 6
0
static void sport_free_resource(struct sport_device *sport)
{
	free_irq(sport->rx_err_irq, sport);
	free_irq(sport->tx_err_irq, sport);
	free_dma(sport->rx_dma_chan);
	free_dma(sport->tx_dma_chan);
	peripheral_free_list(sport->pin_req);
}
Ejemplo n.º 7
0
static void znet_release_resources (struct net_device *dev)
{
	struct znet_private *znet = netdev_priv(dev);

	release_region (znet->sia_base, znet->sia_size);
	release_region (dev->base_addr, znet->io_size);
	free_dma (znet->tx_dma);
	free_dma (znet->rx_dma);
	free_irq (dev->irq, dev);
}
Ejemplo n.º 8
0
static void ccat_dma_free(struct ccat_eth_priv *const priv)
{
	if (priv->dma_mem.base) {
		const struct ccat_dma_mem tmp = priv->dma_mem;

		memset(&priv->dma_mem, 0, sizeof(priv->dma_mem));
		dma_free_coherent(tmp.dev, tmp.size, tmp.base, tmp.phys);
		free_dma(priv->func->info.tx_dma_chan);
		free_dma(priv->func->info.rx_dma_chan);
	}
}
Ejemplo n.º 9
0
static void znet_release_resources (struct net_device *dev)
{
	struct znet_private *znet = netdev_priv(dev);
	unsigned long flags;

	release_region (znet->sia_base, znet->sia_size);
	release_region (dev->base_addr, znet->io_size);
	flags = claim_dma_lock();
	free_dma (znet->tx_dma);
	free_dma (znet->rx_dma);
	release_dma_lock (flags);
	free_irq (dev->irq, dev);
}
Ejemplo n.º 10
0
static int sport_request_resource(struct sport_device *sport)
{
	struct device *dev = &sport->pdev->dev;
	int ret;

	ret = peripheral_request_list(sport->pin_req, "soc-audio");
	if (ret) {
		dev_err(dev, "Unable to request sport pin\n");
		return ret;
	}

	ret = request_dma(sport->tx_dma_chan, "SPORT TX Data");
	if (ret) {
		dev_err(dev, "Unable to allocate DMA channel for sport tx\n");
		goto err_tx_dma;
	}
	set_dma_callback(sport->tx_dma_chan, sport_tx_irq, sport);

	ret = request_dma(sport->rx_dma_chan, "SPORT RX Data");
	if (ret) {
		dev_err(dev, "Unable to allocate DMA channel for sport rx\n");
		goto err_rx_dma;
	}
	set_dma_callback(sport->rx_dma_chan, sport_rx_irq, sport);

	ret = request_irq(sport->tx_err_irq, sport_err_irq,
			0, "SPORT TX ERROR", sport);
	if (ret) {
		dev_err(dev, "Unable to allocate tx error IRQ for sport\n");
		goto err_tx_irq;
	}

	ret = request_irq(sport->rx_err_irq, sport_err_irq,
			0, "SPORT RX ERROR", sport);
	if (ret) {
		dev_err(dev, "Unable to allocate rx error IRQ for sport\n");
		goto err_rx_irq;
	}

	return 0;
err_rx_irq:
	free_irq(sport->tx_err_irq, sport);
err_tx_irq:
	free_dma(sport->rx_dma_chan);
err_rx_dma:
	free_dma(sport->tx_dma_chan);
err_tx_dma:
	peripheral_free_list(sport->pin_req);
	return ret;
}
Ejemplo n.º 11
0
void __exit bf561_coreb_exit(void)
{
	remove_proc_entry("coreb/status", coreb_proc_entry);
	remove_proc_entry("coreb", NULL);

	misc_deregister(&coreb_dev);

	release_mem_region(0xff610000, 0x4000);
	release_mem_region(0xff600000, 0x4000);
	release_mem_region(0xff500000, 0x8000);
	release_mem_region(0xff400000, 0x8000);

	free_dma(CH_MEM_STREAM2_DEST);
	free_dma(CH_MEM_STREAM2_SRC);
}
Ejemplo n.º 12
0
static int snd_ad1816a_free(struct snd_ad1816a *chip)
{
	release_and_free_resource(chip->res_port);
	if (chip->irq >= 0)
		free_irq(chip->irq, (void *) chip);
	if (chip->dma1 >= 0) {
		snd_dma_disable(chip->dma1);
		free_dma(chip->dma1);
	}
	if (chip->dma2 >= 0) {
		snd_dma_disable(chip->dma2);
		free_dma(chip->dma2);
	}
	return 0;
}
Ejemplo n.º 13
0
static int __init setup_card(unsigned long io, unsigned irq, unsigned char dma)
{
	int res = -ENOMEM;
	struct proteon_card *this_card;
	struct net_device *dev = alloc_trdev(0);

	if (dev) {
		dev->base_addr = io;
		dev->irq       = irq;
		dev->dma       = dma;
		res = -ENODEV;
		if (proteon_probe(dev) == 0) {
			res = register_netdev(dev);
			if (!res)
				return 0;
			release_region(dev->base_addr, PROTEON_IO_EXTENT);
			free_irq(dev->irq, dev);
			free_dma(dev->dma);
			tmsdev_term(dev);
			this_card = proteon_card_list;
			proteon_card_list = this_card->next;
			kfree(this_card);
		}
		kfree(dev);
	}
	return res;
}
Ejemplo n.º 14
0
static void __exit ltpc_cleanup(void)
{

	if(debug & DEBUG_VERBOSE) printk("unregister_netdev\n");
	unregister_netdev(dev_ltpc);

	ltpc_timer.data = 0;  /* signal the poll routine that we're done */

	del_timer_sync(&ltpc_timer);

	if(debug & DEBUG_VERBOSE) printk("freeing irq\n");

	if (dev_ltpc->irq)
		free_irq(dev_ltpc->irq, dev_ltpc);

	if(debug & DEBUG_VERBOSE) printk("freeing dma\n");

	if (dev_ltpc->dma)
		free_dma(dev_ltpc->dma);

	if(debug & DEBUG_VERBOSE) printk("freeing ioaddr\n");

	if (dev_ltpc->base_addr)
		release_region(dev_ltpc->base_addr,8);

	free_netdev(dev_ltpc);

	if(debug & DEBUG_VERBOSE) printk("free_pages\n");

	free_pages( (unsigned long) ltdmabuf, get_order(1000));

	if(debug & DEBUG_VERBOSE) printk("returning from cleanup_module\n");
}
Ejemplo n.º 15
0
static int elp_close(struct net_device *dev)
{
	elp_device *adapter = netdev_priv(dev);

	if (elp_debug >= 3)
		pr_debug("%s: request to close device\n", dev->name);

	netif_stop_queue(dev);

	/*                                                               
                                                                     
                                                                         
  */
	(void) elp_get_stats(dev);

	/*
                                   
  */
	outb_control(0, dev);

	/*
                   
  */
	free_irq(dev->irq, dev);

	free_dma(dev->dma);
	free_pages((unsigned long) adapter->dma_buffer, get_order(DMA_BUFFER_SIZE));

	return 0;
}
Ejemplo n.º 16
0
/*
 * Do the necessary ALSA-level cleanup to deallocate our driver ...
 */
static void soundscape_free(struct snd_card *c)
{
	struct soundscape *sscape = get_card_soundscape(c);
	release_and_free_resource(sscape->io_res);
	release_and_free_resource(sscape->wss_res);
	free_dma(sscape->chip->dma1);
}
Ejemplo n.º 17
0
static int dma_init(void) {
    int ret;

    /* Request DMA channel */
    ret = request_dma(CH_PPI, DRIVER_NAME);
    if(ret < 0) {
        printk(KERN_WARNING DRIVER_NAME ": Could not allocate DMA channel\n");
        return ret;
    }

    /* Disable channel while it is being configured */
    disable_dma(CH_PPI);

    /* Allocate buffer space for the DMA engine to use */
    dma_buffer = __get_dma_pages(GFP_KERNEL, page_alloc_order(BUFFER_SIZE * BUFFER_COUNT));
    if(dma_buffer == 0) {
        printk(KERN_WARNING DRIVER_NAME ": Could not allocate dma_pages\n");
        free_dma(CH_PPI);
        return -ENOMEM;
    }

    /* Invalid caching on the DMA buffer */
    invalidate_dcache_range(dma_buffer, dma_buffer + (BUFFER_SIZE * BUFFER_COUNT));

    /* Set DMA configuration */
    set_dma_start_addr(CH_PPI, dma_buffer);
    set_dma_config(CH_PPI, (DMAFLOW_AUTO | WNR | RESTART | DI_EN | WDSIZE_16 | DMA2D | DI_SEL));
    set_dma_x_count(CH_PPI, SAMPLES_PER_BUFFER * CHANNELS);
    set_dma_x_modify(CH_PPI, SAMPLE_SIZE);
    set_dma_y_count(CH_PPI, BUFFER_COUNT);
    set_dma_y_modify(CH_PPI, SAMPLE_SIZE);
    set_dma_callback(CH_PPI, &buffer_full_handler, NULL);

    return 0;
}
Ejemplo n.º 18
0
static void b44_free_tx_ring(struct b44_private *bp)
{
	if (bp->tx) {
		free_dma(bp->tx, B44_TX_RING_LEN_BYTES);
		bp->tx = NULL;
	}
}
Ejemplo n.º 19
0
/*
 * FUNCTION NAME: ppi_release
 *
 * INPUTS/OUTPUTS:
 * in_inode - Description of openned file.
 * in_filp - Description of openned file.
 *
 * RETURN
 * Always 0
 *
 * FUNCTION(S) CALLED:
 *
 * GLOBAL VARIABLES REFERENCED: ppiinfo
 *
 * GLOBAL VARIABLES MODIFIED: NIL
 *
 * DESCRIPTION: It is invoked when user call 'close' system call
 *              to close device.
 *
 * CAUTION:
 */
static int ppi_release(struct inode *inode, struct file *filp)
{

	unsigned long flags;
	ppi_device_t *pdev = filp->private_data;

	pr_debug("ppi_release: close()\n");

	spin_lock_irqsave(&ppifcd_lock, flags);
	/* After finish DMA, release it. */
	free_dma(CH_PPI);

	free_irq(IRQ_PPI_ERROR, filp->private_data);

	if (pdev->ppi_trigger_gpio > NO_TRIGGER)
		gpio_free(pdev->ppi_trigger_gpio);

	ppifcd_reg_reset(pdev);
	pdev->opened = 0;
	spin_unlock_irqrestore(&ppifcd_lock, flags);

	ppi_fasync(-1, filp, 0);

	pr_debug("ppi_release: close() return\n");
	return 0;
}
Ejemplo n.º 20
0
/* The inverse routine to net_open(). */
static int
net_close(struct device *dev)
{
	struct net_local *lp = (struct net_local *)dev->priv;
	int ioaddr = dev->base_addr;

	lp->open_time = 0;

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

	/* Flush the Tx and disable Rx here. */

	disable_dma(dev->dma);

	/* If not IRQ or DMA jumpered, free up the line. */
	outw(0x00, ioaddr+0);		/* Release the physical interrupt line. */

	free_irq(dev->irq);
	free_dma(dev->dma);

	irq2dev_map[dev->irq] = 0;

	/* Update the statistics here. */

	return 0;

}
Ejemplo n.º 21
0
/*
 * Do the necessary ALSA-level cleanup to deallocate our driver ...
 */
static void soundscape_free(snd_card_t * c)
{
	register struct soundscape *sscape = get_card_soundscape(c);
	release_resource(sscape->io_res);
	kfree_nocheck(sscape->io_res);
	free_dma(sscape->chip->dma1);
}
Ejemplo n.º 22
0
/**
 * Destroy descriptor ring
 *
 * @v netfront		Netfront device
 * @v ring		Descriptor ring
 * @v discard		Method used to discard outstanding buffer, or NULL
 */
static void netfront_destroy_ring ( struct netfront_nic *netfront,
				    struct netfront_ring *ring,
				    void ( * discard ) ( struct io_buffer * ) ){
	struct xen_device *xendev = netfront->xendev;
	struct xen_hypervisor *xen = xendev->xen;
	struct io_buffer *iobuf;
	unsigned int id;

	/* Flush any outstanding buffers */
	while ( ! netfront_ring_is_empty ( ring ) ) {
		id = ring->ids[ ring->id_cons & ( ring->count - 1 ) ];
		iobuf = netfront_pull ( netfront, ring, id );
		if ( discard )
			discard ( iobuf );
	}

	/* Unpublish shared ring reference */
	netfront_rm ( netfront, ring->ref_key );

	/* Revoke access from shared ring */
	xengrant_invalidate ( xen, ring->ref );

	/* Free page */
	free_dma ( ring->sring.raw, PAGE_SIZE );
	ring->sring.raw = NULL;
}
Ejemplo n.º 23
0
static int elp_close(struct net_device *dev)
{
	elp_device *adapter;

	adapter = dev->priv;

	if (elp_debug >= 3)
		printk(KERN_DEBUG "%s: request to close device\n", dev->name);

	netif_stop_queue(dev);

	/* Someone may request the device statistic information even when
	 * the interface is closed. The following will update the statistics
	 * structure in the driver, so we'll be able to give current statistics.
	 */
	(void) elp_get_stats(dev);

	/*
	 * disable interrupts on the board
	 */
	outb_control(0, dev);

	/*
	 * release the IRQ
	 */
	free_irq(dev->irq, dev);

	free_dma(dev->dma);
	free_pages((unsigned long) adapter->dma_buffer, get_order(DMA_BUFFER_SIZE));

	return 0;
}
Ejemplo n.º 24
0
static void
e1000_free_tx_resources ( struct e1000_adapter *adapter )
{
	DBG ( "e1000_free_tx_resources\n" );

        free_dma ( adapter->tx_base, adapter->tx_ring_size );
}
Ejemplo n.º 25
0
static void ppi_detach_irq(struct ppi_if *ppi)
{
	const struct ppi_info *info = ppi->info;

	if (ppi->err_int)
		free_irq(info->irq_err, ppi);
	free_dma(info->dma_ch);
}
Ejemplo n.º 26
0
static int bfin_sir_startup(struct bfin_sir_port *port, struct net_device *dev)
{
#ifdef CONFIG_SIR_BFIN_DMA
	dma_addr_t dma_handle;
#endif /* CONFIG_SIR_BFIN_DMA */

	if (request_dma(port->rx_dma_channel, "BFIN_UART_RX") < 0) {
		dev_warn(&dev->dev, "Unable to attach SIR RX DMA channel\n");
		return -EBUSY;
	}

	if (request_dma(port->tx_dma_channel, "BFIN_UART_TX") < 0) {
		dev_warn(&dev->dev, "Unable to attach SIR TX DMA channel\n");
		free_dma(port->rx_dma_channel);
		return -EBUSY;
	}

#ifdef CONFIG_SIR_BFIN_DMA

	set_dma_callback(port->rx_dma_channel, bfin_sir_dma_rx_int, dev);
	set_dma_callback(port->tx_dma_channel, bfin_sir_dma_tx_int, dev);

	port->rx_dma_buf.buf = dma_alloc_coherent(NULL, PAGE_SIZE,
						  &dma_handle, GFP_DMA);
	port->rx_dma_buf.head = 0;
	port->rx_dma_buf.tail = 0;
	port->rx_dma_nrows = 0;

	set_dma_config(port->rx_dma_channel,
				set_bfin_dma_config(DIR_WRITE, DMA_FLOW_AUTO,
									INTR_ON_ROW, DIMENSION_2D,
									DATA_SIZE_8, DMA_SYNC_RESTART));
	set_dma_x_count(port->rx_dma_channel, DMA_SIR_RX_XCNT);
	set_dma_x_modify(port->rx_dma_channel, 1);
	set_dma_y_count(port->rx_dma_channel, DMA_SIR_RX_YCNT);
	set_dma_y_modify(port->rx_dma_channel, 1);
	set_dma_start_addr(port->rx_dma_channel, (unsigned long)port->rx_dma_buf.buf);
	enable_dma(port->rx_dma_channel);

	port->rx_dma_timer.data = (unsigned long)(dev);
	port->rx_dma_timer.function = (void *)bfin_sir_rx_dma_timeout;

#else

	if (request_irq(port->irq, bfin_sir_rx_int, 0, "BFIN_SIR_RX", dev)) {
		dev_warn(&dev->dev, "Unable to attach SIR RX interrupt\n");
		return -EBUSY;
	}

	if (request_irq(port->irq+1, bfin_sir_tx_int, 0, "BFIN_SIR_TX", dev)) {
		dev_warn(&dev->dev, "Unable to attach SIR TX interrupt\n");
		free_irq(port->irq, dev);
		return -EBUSY;
	}
#endif

	return 0;
}
Ejemplo n.º 27
0
/**
 * Free I/O buffer
 *
 * @v iobuf	I/O buffer
 */
void free_iob ( struct io_buffer *iobuf ) {
	if ( iobuf ) {
		assert ( iobuf->head <= iobuf->data );
		assert ( iobuf->data <= iobuf->tail );
		assert ( iobuf->tail <= iobuf->end );
		free_dma ( iobuf->head,
			   ( iobuf->end - iobuf->head ) + sizeof ( *iobuf ) );
	}
}
Ejemplo n.º 28
0
static int snd_sbdsp_free(struct snd_sb *chip)
{
	release_and_free_resource(chip->res_port);
	if (chip->irq >= 0)
		free_irq(chip->irq, (void *) chip);
#ifdef CONFIG_ISA
	if (chip->dma8 >= 0) {
		disable_dma(chip->dma8);
		free_dma(chip->dma8);
	}
	if (chip->dma16 >= 0 && chip->dma16 != chip->dma8) {
		disable_dma(chip->dma16);
		free_dma(chip->dma16);
	}
#endif
	kfree(chip);
	return 0;
}
Ejemplo n.º 29
0
int pnp_check_dma(struct pnp_dev * dev, int idx)
{
#ifndef CONFIG_IA64
	int tmp;
	struct pnp_dev *tdev;
	unsigned long * dma = &dev->res.dma_resource[idx].start;

	/* if the resource doesn't exist, don't complain about it */
	if (cannot_compare(dev->res.dma_resource[idx].flags))
		return 1;

	/* check if the resource is valid */
	if (*dma < 0 || *dma == 4 || *dma > 7)
		return 0;

	/* check if the resource is reserved */
	for (tmp = 0; tmp < 8; tmp++) {
		if (pnp_reserve_dma[tmp] == *dma)
			return 0;
	}

	/* check for internal conflicts */
	for (tmp = 0; tmp < PNP_MAX_DMA && tmp != idx; tmp++) {
		if (dev->res.dma_resource[tmp].flags & IORESOURCE_DMA) {
			if (dev->res.dma_resource[tmp].start == *dma)
				return 0;
		}
	}

	/* check if the resource is already in use, skip if the
	 * device is active because it itself may be in use */
	if(!dev->active) {
		if (request_dma(*dma, "pnp"))
			return 0;
		free_dma(*dma);
	}

	/* check for conflicts with other pnp devices */
	pnp_for_each_dev(tdev) {
		if (tdev == dev)
			continue;
		for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) {
			if (tdev->res.dma_resource[tmp].flags & IORESOURCE_DMA) {
				if (cannot_compare(tdev->res.dma_resource[tmp].flags))
					continue;
				if ((tdev->res.dma_resource[tmp].start == *dma))
					return 0;
			}
		}
	}

	return 1;
#else
	/* IA64 hasn't legacy DMA */
	return 0;
#endif
}
Ejemplo n.º 30
0
static void wbsd_init_dma(struct wbsd_host* host)
{
	host->dma = -1;
	
	if (dma < 0)
		return;
	
	if (request_dma(dma, DRIVER_NAME))
		goto err;
	
	/*
	 * We need to allocate a special buffer in
	 * order for ISA to be able to DMA to it.
	 */
	host->dma_buffer = kmalloc(65536,
		GFP_NOIO | GFP_DMA | __GFP_REPEAT | __GFP_NOWARN);
	if (!host->dma_buffer)
		goto free;

	/*
	 * Translate the address to a physical address.
	 */
	host->dma_addr = isa_virt_to_bus(host->dma_buffer);
			
	/*
	 * ISA DMA must be aligned on a 64k basis.
	 */
	if ((host->dma_addr & 0xffff) != 0)
		goto kfree;
	/*
	 * ISA cannot access memory above 16 MB.
	 */
	else if (host->dma_addr >= 0x1000000)
		goto kfree;

	host->dma = dma;
	
	return;
	
kfree:
	/*
	 * If we've gotten here then there is some kind of alignment bug
	 */
	BUG_ON(1);
	
	kfree(host->dma_buffer);
	host->dma_buffer = NULL;

free:
	free_dma(dma);

err:
	printk(KERN_WARNING DRIVER_NAME ": Unable to allocate DMA %d. "
		"Falling back on FIFO.\n", dma);
}