+++ /dev/null
-/*
- comedi/drivers/amcc_s5933.h
-
- Stuff for AMCC S5933 PCI Controller
-
- Author: Michal Dobes <dobes@tesnet.cz>
-
- Inspirated from general-purpose AMCC S5933 PCI Matchmaker driver
- made by Andrea Cisternino <acister@pcape1.pi.infn.it>
- and as result of espionage from MITE code made by David A. Schleef.
- Thanks to AMCC for their on-line documentation and bus master DMA
- example.
-*/
-
-#include <linux/comedidev.h>
-
-#include <linux/pci.h>
-
-#include "amcc_s5933.h"
-
-
-/****************************************************************************/
-
-/* build list of amcc cards in this system */
-void pci_card_list_init(unsigned short pci_vendor, char display)
-{
- struct pci_dev *pcidev;
- struct pcilst_struct *amcc,*last;
- int i;
-
- amcc_devices=NULL;
- last=NULL;
-
- for(pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pcidev != NULL ;
- pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
- if(pcidev->vendor==pci_vendor){
- amcc=kmalloc(sizeof(*amcc),GFP_KERNEL);
- if (!amcc) {
- printk("amcc_s5933: allocation failed\n");
- pci_dev_put(pcidev);
- break;
- }
- memset(amcc,0,sizeof(*amcc));
-
- amcc->pcidev=pci_dev_get(pcidev);
- if (last) { last->next=amcc; }
- else { amcc_devices=amcc; }
- last=amcc;
-
- amcc->vendor=pcidev->vendor;
- amcc->device=pcidev->device;
- amcc->pci_bus=pcidev->bus->number;
- amcc->pci_slot=PCI_SLOT(pcidev->devfn);
- amcc->pci_func=PCI_FUNC(pcidev->devfn);
- /* Note: resources may be invalid if PCI device
- * not enabled, but they are corrected in
- * pci_card_alloc. */
- for (i=0;i<5;i++)
- amcc->io_addr[i]=pci_resource_start(pcidev, i);
- amcc->irq=pcidev->irq;
-#if LINUX_VERSION_CODE < 0x020300
- amcc->master=pcidev->master;
-#else
- amcc->master=1;
-#endif
-
- }
- }
-
- if (display) pci_card_list_display();
-}
-
-/****************************************************************************/
-/* free up list of amcc cards in this system */
-void pci_card_list_cleanup(unsigned short pci_vendor)
-{
- struct pcilst_struct *amcc,*next;
-
- for(amcc=amcc_devices;amcc;amcc=next){
- pci_dev_put(amcc->pcidev);
- next=amcc->next;
- kfree(amcc);
- }
-
- amcc_devices=NULL;
-}
-
-/****************************************************************************/
-/* find first unused card with this device_id */
-struct pcilst_struct *find_free_pci_card_by_device(unsigned short vendor_id, unsigned short device_id)
-{
- struct pcilst_struct *amcc,*next;
-
- for (amcc=amcc_devices;amcc;amcc=next) {
- next=amcc->next;
- if ((!amcc->used)&&(amcc->device==device_id)&&(amcc->vendor==vendor_id)) return amcc;
-
- }
-
- return NULL;
-}
-
-/****************************************************************************/
-/* find card on requested position */
-int find_free_pci_card_by_position(unsigned short vendor_id, unsigned short device_id, unsigned short pci_bus, unsigned short pci_slot, struct pcilst_struct **card)
-{
- struct pcilst_struct *amcc,*next;
-
- *card=NULL;
- for (amcc=amcc_devices;amcc;amcc=next) {
- next=amcc->next;
- if ((amcc->vendor==vendor_id)&&(amcc->device==device_id)&&(amcc->pci_bus==pci_bus)&&(amcc->pci_slot==pci_slot)) {
- if (!(amcc->used)) {
- *card=amcc;
- return 0; // ok, card is found
- } else {
- return 2; // card exist but is used
- }
- }
- }
-
- return 1; // no card found
-}
-
-/****************************************************************************/
-/* mark card as used */
-int pci_card_alloc(struct pcilst_struct *amcc, char master)
-{
- int i;
-
- if (!amcc) {
- rt_printk(" - BUG!! amcc is NULL!\n");
- return -1;
- }
-
- if (amcc->used) return 1;
- if (pci_enable_device(amcc->pcidev)) {
- rt_printk(" - Can't enable PCI device!\n");
- return -1;
- }
- /* Resources will be accurate now. */
- for (i=0;i<5;i++)
- amcc->io_addr[i]=pci_resource_start(amcc->pcidev, i);
- amcc->irq=amcc->pcidev->irq;
- /* Request regions on behalf of client. */
- if (pci_request_regions(amcc->pcidev, "amcc_s5933")) {
- rt_printk(" - I/O port conflict!\n");
- return -1;
- }
- if (master) pci_set_master(amcc->pcidev);
- amcc->used=1;
-
- return 0;
-}
-
-/****************************************************************************/
-/* mark card as free */
-int pci_card_free(struct pcilst_struct *amcc)
-{
- if (!amcc) return -1;
-
- if (!amcc->used) return 1;
- amcc->used=0;
- pci_release_regions(amcc->pcidev);
- pci_disable_device(amcc->pcidev);
- return 0;
-}
-
-/****************************************************************************/
-/* display list of found cards */
-void pci_card_list_display(void)
-{
- struct pcilst_struct *amcc,*next;
-
- printk("List of pci cards\n");
- printk("bus:slot:func vendor device master io_amcc io_daq irq used\n");
-
- for (amcc=amcc_devices;amcc;amcc=next) {
- next=amcc->next;
- printk("%2d %2d %2d 0x%4x 0x%4x %3s 0x%4x 0x%4x %2d %2d\n",
- amcc->pci_bus,amcc->pci_slot,amcc->pci_func,amcc->vendor,amcc->device,amcc->master?"yes":"no",
- amcc->io_addr[0],amcc->io_addr[2],amcc->irq,amcc->used);
-
- }
-}
-
-/****************************************************************************/
-/* return all card information for driver */
-int pci_card_data(struct pcilst_struct *amcc,
- unsigned char *pci_bus, unsigned char *pci_slot, unsigned char *pci_func,
- unsigned short *io_addr, unsigned short *irq, unsigned short *master)
-{
- int i;
-
- if (!amcc) return -1;
- *pci_bus=amcc->pci_bus;
- *pci_slot=amcc->pci_slot;
- *pci_func=amcc->pci_func;
- for (i=0;i<5;i++)
- io_addr[i]=amcc->io_addr[i];
- *irq=amcc->irq;
- *master=amcc->master;
- return 0;
-}
-
-/****************************************************************************/
-/* select and alloc card */
-struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id, unsigned short device_id, unsigned short pci_bus, unsigned short pci_slot, char master)
-{
- struct pcilst_struct *card;
- int err;
-
- if ((pci_bus<1)&&(pci_slot<1)) { // use autodetection
- if ((card=find_free_pci_card_by_device(vendor_id,device_id))==NULL) {
- rt_printk(" - Unused card not found in system!\n");
- return NULL;
- }
- } else {
- switch (find_free_pci_card_by_position(vendor_id,device_id,pci_bus,pci_slot,&card)) {
- case 1:
- rt_printk(" - Card not found on requested position b:s %d:%d!\n",pci_bus,pci_slot);
- return NULL;
- case 2:
- rt_printk(" - Card on requested position is used b:s %d:%d!\n",pci_bus,pci_slot);
- return NULL;
- }
- }
-
-
- if ((err=pci_card_alloc(card, master))!=0) {
- if (err > 0)
- rt_printk(" - Can't allocate card!\n");
- /* else: error already printed. */
- return NULL;
- }
-
- return card;
-}
-
-
-static int amcc_init(void)
-{
- return 0;
-}
-
-static void amcc_cleanup(void)
-{
-
-}
-
-MODULE_AUTHOR("Michal Dobes <dobes@tesnet.cz>");
-MODULE_DESCRIPTION("Driver for AMCC 5933 PCI controller");
-MODULE_LICENSE("GPL");
-
-module_init(amcc_init);
-module_exit(amcc_cleanup);
-
-EXPORT_SYMBOL(pci_card_alloc);
-EXPORT_SYMBOL(pci_card_data);
-EXPORT_SYMBOL(pci_card_free);
-EXPORT_SYMBOL(pci_card_list_cleanup);
-EXPORT_SYMBOL(pci_card_list_display);
-EXPORT_SYMBOL(pci_card_list_init);
-EXPORT_SYMBOL(select_and_alloc_pci_card);
-EXPORT_SYMBOL(find_free_pci_card_by_device);
-EXPORT_SYMBOL(find_free_pci_card_by_position);
-EXPORT_SYMBOL(amcc_devices);
-
-
-