// kolter.h for getting the base address of a kolter pci card. // // Tested on i386 Linux (SuSE 6.4), should work on PPC and alpha. // // The function get_first_kolter_pci_device_baseaddress(dev_id) returns the base address // of the kolter card with the device id dev_id if the return value is positiv and returns // the (negative) error number if the return value is negetiv. // This function can be use for kernel space programs and also for user space programs. // // With the base address the (16 bit) I/O can be done with // in_value=inw(base+address_on_card) and outw(value,base+address_on_card). // // vendor tables, device id tables etc. can be found at http://www.yourvote.com/pci /* 2000 Rolf Freitag, rolf.freitag at email.de This Program is free software; you can redistribute it and/od modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at yout option) any later version. This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRENTY; without even the implied warrenty of MERCHANTABILITY of FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this Program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef KOLTER_VENDOR_ID # undef KOLTER_VENDOR_ID #endif #define KOLTER_VENDOR_ID 0x1001 // Vendor ID from KOLTER #ifdef __KERNEL__ // usual file functions like fopen are not available in kernel space #include // CONFIG_PCI #include // pcibios_find_device .. #include // ENODEV ... #include // printk() #ifdef CONFIG_PCI // if PCI-BIOS can be found long long int get_first_kolter_pci_device_baseaddress (unsigned short dev_id) { const unsigned short vendor = KOLTER_VENDOR_ID; //unsigned char bus = 0; // number of the PCI bus //unsigned char dev_fn = 0; // device function //unsigned short index = 0; // index; the first card has 0 //unsigned short int i = 0; // index for counting int result = PCIBIOS_SUCCESSFUL; // for result value from pcibios_find_device unsigned int count = 0; // counter for the kolter cards unsigned int base = 0xffffffff; // base address of the first kolter card struct pci_dev *pptr = malloc (sizeof (*pptr), GFP_KERNEL); if (!pptr) return ((long long int) -ENODEV); // no device // search the cards /* for (i = 0; i < 255 && result == PCIBIOS_SUCCESSFUL; i++) { index = i; result = pcibios_find_device (vendor, dev_id, index, &bus, &dev_fn); if (result == PCIBIOS_SUCCESSFUL) count++; } */ if (pci_find_device (vendor, dev_id, pptr)) count = 1; // get the base address of the card if (count > 1) printk (KERN_CRIT "Waring: more than one card with vendor 0x%hx and dev_id 0x%hx is present.\n", vendor, dev_id); if (count >= 1) { // pcibios_read_config_dword (bus, dev_fn, PCI_BASE_ADDRESS_0, &base); pci_read_config_dword (pptr, PCI_BASE_ADDRESS_0, &base); free (pptr); return ((long long int) (base & 0xfffffffe)); // return the even base address } else { printk (KERN_CRIT "No card with vendor 0x%hx and dev_id 0x%hx could be found, ", vendor, dev_id); printk (KERN_CRIT "pci error: %d (see /usr/include/linux/pci.h).\n", result); free (pptr); return ((long long int) -ENODEV); // no device } } #endif // CONFIG_PCI #else // user space, pci functions are kernel space functions and not available here #include #include #include #include // ENODEV ... long long int get_first_kolter_pci_device_baseaddress (unsigned short dev_id) // This function searches in /proc/pci for the kolter card with the device id dev_id. { const unsigned short vendor = KOLTER_VENDOR_ID; unsigned int count = 0; // counter for the kolter cards unsigned int base = 0xffffffff; // base address of the first kolter card unsigned int region = 0; // (first) region of the first kolter card static FILE *fp = NULL; // input file pointer for /proc/pci char line[4096] = ""; //unsigned short v = 0, d = 0; // for sscanf char s1[4096] = ""; int i0=0, i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0, i8=0, i9=0, i10=0; // search the first card fp = fopen ("/proc/bus/pci/devices", "r"); if (NULL == fp) { printf("Could not open the PCI info file /proc/bus/pci/devices, exiting.\n"); exit (-1); } while (fgets (line, 4096, fp) != NULL) // line reading { if (sscanf (line, "%x %x %x %x %x %x %x %x %x %x %x %s", &i0, &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8, &i9, &i10, s1) == 12 && ( (vendor * 0x10000) + dev_id) == i1 ) { if (0 == count) // first card { base = i3; region = i10; } count++; } } if (count == 0) { fprintf (stderr, "ERROR: PCI error: no card with vendor %hx and dev_id %hx found.\n", vendor, dev_id); return ((long long int) -ENODEV); // no device } if (count > 1) fprintf (stderr, "Waring: more than one card with vendor %hx and dev_id %hx is present.\n", vendor, dev_id); return ((long long int) base); } #endif // else from ifdef __KERNEL__ #undef KOLTER_VENDOR_ID