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