Re: [PARPORT] Lava Parallel Accelerator


Alan Cox (alan@lxorguk.ukuu.org.uk)
Tue, 19 Jan 1999 22:57:43 +0000 (GMT)


> Would it be something like this? (I'm only glancing at pci.h)
>
> struct pci_dev *dev = pci_find_device (0x1407, 0x8000, pci_devices);
>
> while (dev) {
> /* probe io=dev->base_address[0] irq=dev->irq */
>
> dev = pci_find_device (0x1407, 0x8000, dev);
> }

You have to diddle with the addresses - they are encoded. Here's an example
which is a sound driver

/*
 * PCI sound skeleton example
 *
 * (c) 1998 Red Hat Software
 *
 * This software may be used and distributed according to the
 * terms of the GNU Public License, incorporated herein by
 * reference.
 *
 * This example is designed to be built in the linux/drivers/sound
 * directory as part of a kernel build. The example is modular only
 * drop me a note once you have a working modular driver and want
 * to integrate it with the main code.
 * -- Alan <alan@redhat.com>
 *
 * This is a first draft. Please report any errors, corrections or
 * improvements to me.
 */

#include <linux/module.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/pci.h>

#include <asm/io.h>

#include "sound_config.h"
#include "soundmodule.h"

/*
 * Define our PCI vendor ID here
 */
 
#ifndef PCI_VENDOR_MYIDENT
#define PCI_VENDOR_MYIDENT 0x125D

/*
 * PCI identity for the card.
 */
 
#define PCI_DEVICE_ID_MYIDENT_MYCARD1 0x1969
#endif

#define CARD_NAME "ExampleWave 3D Pro Ultra ThingyWotsit"

#define MAX_CARDS 8

/*
 * Each address_info object holds the information about one of
 * our card resources. In this case the MSS emulation of our
 * ficticious card. Its used to manage and attach things.
 */
 
static struct address_info mss_data[MAX_CARDS];
static int cards = 0;

/*
 * Install the actual card. This is an example
 */

static int mycard_install(struct pci_dev *pcidev)
{
        int iobase;
        int mssbase;
        int mpubase;
        u8 x;
        u16 w;
        u32 v;
        int i;
        int dma;

        /*
         * Our imaginary code has its I/O on PCI address 0, a
         * MSS on PCI address 1 and an MPU on address 2
         *
         * For the example we will only initialise the MSS
         */
                 
        iobase = pcidev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK;
        mssbase = pcidev->base_address[1] & PCI_BASE_ADDRESS_IO_MASK;
        mpubase = pcidev->base_address[2] & PCI_BASE_ADDRESS_IO_MASK;
        
        /*
         * Reset the board
         */
         
        /*
         * Wait for completion. udelay() waits in microseconds
         */
         
        udelay(100);
        
        /*
         * Ok card ready. Begin setup proper. You might for example
         * load the firmware here
         */
        
        dma = card_specific_magic(ioaddr);
        
        /*
         * Turn on legacy mode (example), There are also byte and
         * dword (32bit) PCI configuration function calls
         */

        pci_read_config_word(pcidev, 0x40, &w);
        w&=~(1<<15); /* legacy decode on */
        w|=(1<<14); /* Reserved write as 1 in this case */
        w|=(1<<3)|(1<<1)|(1<<0); /* SB on , FM on, MPU on */
        pci_write_config_word(pcidev, 0x40, w);
        
        /*
         * Let the user know we found his toy.
         */
         
        printk(KERN_INFO "Programmed "CARD_NAME" at 0x%X to legacy mode.\n",
                iobase);
                
        /*
         * Now set it up the description of the card
         */
         
        mss_data[cards].io_base = mssbase;
        mss_data[cards].irq = pcidev->irq;
        mss_data[cards].dma = dma;
        
        /*
         * Check there is an MSS present
         */

        if(ad1848_detect(mssbase, NULL, mss_data[cards].osp)==0)
                return 0;
                
        /*
         * Initialize it
         */
         
        mss_data[cards].slots[3] = ad1848_init("MyCard MSS 16bit",
                        mssbase, mss_data[cards].irq);

        cards++;
        return 1;
}

/*
 * This loop walks the PCI configuration database and finds where
 * the sound cards are.
 */
 
int init_mycard(void)
{
        struct pci_dev *pcidev=NULL;
        int count=0;
                
        if(!pci_present())
                return -ENODEV;
        
                
        while((pcidev = pci_find_device(PCI_VENDOR_MYIDENT, PCI_DEVICE_ID_MYIDENT_MYCARD1, pcidev))!=NULL)
        {
                count+=mycard_install(pcidev);
                if(count)
                        return 0;
                if(count==MAX_CARDS)
                        break;
        }
        
        if(count==0)
                return -ENODEV;
        return 0;
}

/*
 * This function is called when the user or kernel loads the
 * module into memory.
 */

int init_module(void)
{
        if(init_mycard()<0)
        {
                printk(KERN_ERR "No "CARD_NAME" cards found.\n");
                return -ENODEV;
        }
        /*
         * Binds us to the sound subsystem
         */
        SOUND_LOCK;
        return 0;
}

/*
 * This is called when it is removed. It will only be removed
 * when its use count is 0. For sound the SOUND_LOCK/SOUND_UNLOCK
 * macros hide the entire work for this.
 */
 
void cleanup_module(void)
{
        for(i=0;i< cards; i++)
        {
                /*
                 * Free attached resources
                 */
                 
                ad1848_unload(mss_data[i].io_base,
                              mss_data[i].irq,
                              mss_data[i].dma,
                              mss_data[i].dma,
                              0);
                /*
                 * And disconnect the device from the kernel
                 */
                sound_unload_audiodevice(mss_data[i].slots[3]);
        }
        /*
         * Final clean up with the sound layer
         */
        SOUND_LOCK_END;
}

-- To unsubscribe, send mail to: linux-parport-request@torque.net --
-- with the single word "unsubscribe" in the body of the message. --



This archive was generated by hypermail 2.0b3 on Tue 19 Jan 1999 - 17:02:09 EST