00001
00002
00011
00012
00013
00014
00015
00046
00047 #include <l4/env/errno.h>
00048 #include <l4/generic_io/libio.h>
00049 #include <l4/sigma0/kip.h>
00050
00051 #include <l4/dde_linux/dde.h>
00052
00053
00054 #include <linux/pci.h>
00055 #include <linux/list.h>
00056
00057
00058 #include "internal.h"
00059 #include "__config.h"
00060
00065 static struct pcidevs
00066 {
00067 struct pci_dev linus;
00068 l4io_pdev_t l4;
00069 } pcidevs[PCI_DEVICES];
00070
00072 LIST_HEAD(pci_devices);
00073
00075 static struct pci_bus pcibus =
00076 {
00077 name: "LINUX DDE PCI BUS",
00078 number: 0,
00079 };
00080
00082 static int _initialized = 0;
00083
00091 static inline l4io_pdev_t __pci_get_handle(struct pci_dev *linus)
00092 {
00093 return ((struct pcidevs*)linus)->l4;
00094 }
00095
00103 static inline void __pci_io_to_linux(l4io_pci_dev_t *l4io,
00104 struct pci_dev *linus)
00105 {
00106 int i;
00107
00108 memset(linus, 0, sizeof(struct pci_dev));
00109
00110 linus->devfn = l4io->devfn;
00111 linus->vendor = l4io->vendor;
00112 linus->device = l4io->device;
00113 linus->subsystem_vendor = l4io->sub_vendor;
00114 linus->subsystem_device = l4io->sub_device;
00115 linus->class = l4io->dev_class;
00116
00117 linus->irq = l4io->irq;
00118 for (i = 0; i < 12; i++)
00119 {
00120 linus->resource[i].name = linus->name;
00121
00122 linus->resource[i].start = l4io->res[i].start;
00123 linus->resource[i].end = l4io->res[i].end;
00124 linus->resource[i].flags = l4io->res[i].flags;
00125
00126 linus->resource[i].parent = NULL;
00127 linus->resource[i].sibling = NULL;
00128 linus->resource[i].child = NULL;
00129 }
00130
00131 strcpy(&linus->name[0], &l4io->name[0]);
00132 strcpy(&linus->slot_name[0], &l4io->slot_name[0]);
00133
00134 linus->bus = &pcibus;
00135
00136 list_add_tail(&linus->global_list, &pci_devices);
00137 list_add_tail(&linus->bus_list, &pcibus.devices);
00138 }
00139
00152 const struct pci_device_id *pci_match_device(const struct pci_device_id *ids,
00153 const struct pci_dev *dev)
00154 {
00155 while (ids->vendor || ids->subvendor || ids->class_mask)
00156 {
00157 if ((ids->vendor == PCI_ANY_ID || ids->vendor == dev->vendor) &&
00158 (ids->device == PCI_ANY_ID || ids->device == dev->device) &&
00159 (ids->subvendor == PCI_ANY_ID || ids->subvendor == dev->subsystem_vendor) &&
00160 (ids->subdevice == PCI_ANY_ID || ids->subdevice == dev->subsystem_device) &&
00161 !((ids->class ^ dev->class) & ids->class_mask))
00162 return ids;
00163 ids++;
00164 }
00165 return NULL;
00166 }
00167
00175 static int pci_announce_device(struct pci_driver *drv, struct pci_dev *dev)
00176 {
00177 const struct pci_device_id *id;
00178 int ret = 0;
00179
00180 if (drv->id_table)
00181 {
00182 id = pci_match_device(drv->id_table, dev);
00183 if (!id)
00184 {
00185 ret = 0;
00186 goto out;
00187 }
00188 }
00189 else
00190 id = NULL;
00191
00192
00193 if (drv->probe(dev, id) >= 0)
00194 {
00195 dev->driver = drv;
00196 ret = 1;
00197 }
00198
00199 out:
00200 return ret;
00201 }
00202
00210 struct pci_driver *pci_dev_driver(const struct pci_dev *dev)
00211 {
00212 if (dev->driver)
00213 return dev->driver;
00214 return NULL;
00215 }
00216
00230 int pci_register_driver(struct pci_driver *drv)
00231 {
00232 struct pci_dev *dev;
00233 int count = 0;
00234
00235 pci_for_each_dev(dev)
00236 {
00237 if (!pci_dev_driver(dev))
00238 count += pci_announce_device(drv, dev);
00239 }
00240 return count;
00241 }
00242
00250 void pci_unregister_driver(struct pci_driver *drv)
00251 {
00252 struct pci_dev *dev;
00253
00254 pci_for_each_dev(dev)
00255 {
00256 if (dev->driver == drv)
00257 {
00258 if (drv->remove)
00259 drv->remove(dev);
00260 dev->driver = NULL;
00261 }
00262 }
00263 }
00264
00274 struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device,
00275 const struct pci_dev *from)
00276 {
00277 struct list_head *n = from ? from->global_list.next : pci_devices.next;
00278
00279 while (n != &pci_devices)
00280 {
00281 struct pci_dev *dev = pci_dev_g(n);
00282 if ((vendor == PCI_ANY_ID || dev->vendor == vendor) &&
00283 (device == PCI_ANY_ID || dev->device == device))
00284 return dev;
00285 n = n->next;
00286 }
00287
00288 return NULL;
00289 }
00290
00302 struct pci_dev * pci_find_subsys(unsigned int vendor, unsigned int device,
00303 unsigned int ss_vendor, unsigned int ss_device,
00304 const struct pci_dev *from)
00305 {
00306 struct list_head *n = from ? from->global_list.next : pci_devices.next;
00307
00308 while (n != &pci_devices)
00309 {
00310 struct pci_dev *dev = pci_dev_g(n);
00311 if ((vendor == PCI_ANY_ID || dev->vendor == vendor) &&
00312 (device == PCI_ANY_ID || dev->device == device) &&
00313 (ss_vendor == PCI_ANY_ID || dev->subsystem_vendor == ss_vendor) &&
00314 (ss_device == PCI_ANY_ID || dev->subsystem_device == ss_device))
00315 return dev;
00316 n = n->next;
00317 }
00318
00319 return NULL;
00320 }
00321
00330 struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn)
00331 {
00332 struct pci_dev *dev;
00333
00334 pci_for_each_dev(dev)
00335 {
00336 if (dev->bus->number == bus && dev->devfn == devfn)
00337 return dev;
00338 }
00339
00340 return NULL;
00341 }
00342
00351 struct pci_dev *pci_find_class(unsigned int class, const struct pci_dev *from)
00352 {
00353 struct list_head *n = from ? from->global_list.next : pci_devices.next;
00354
00355 while (n != &pci_devices)
00356 {
00357 struct pci_dev *dev = pci_dev_g(n);
00358 if (dev->class == class)
00359 return dev;
00360 n = n->next;
00361 }
00362
00363 return NULL;
00364 }
00365
00366
00367 int pci_find_capability (struct pci_dev *dev, int cap)
00368 {
00369 return 0;
00370 }
00371
00383 int pci_enable_device(struct pci_dev *dev)
00384 {
00385 int err;
00386 l4io_pdev_t pdev;
00387
00388 if (!(pdev=__pci_get_handle(dev)))
00389 {
00390 #if DEBUG_PCI
00391 LOGdL(DEBUG_ERRORS, "device %p not found", dev);
00392 #endif
00393 return PCIBIOS_DEVICE_NOT_FOUND;
00394 }
00395
00396 err = l4io_pci_enable(pdev);
00397
00398 #if DEBUG_PCI
00399 if (err)
00400 LOGdL(DEBUG_ERRORS, "enabling PCI device (%d)", err);
00401 #endif
00402
00403 return err;
00404 }
00405
00411 void pci_disable_device(struct pci_dev *dev)
00412 {
00413 int err;
00414 l4io_pdev_t pdev;
00415
00416 if (!(pdev=__pci_get_handle(dev)))
00417 {
00418 #if DEBUG_PCI
00419 LOGdL(DEBUG_ERRORS, "device %p not found", dev);
00420 #endif
00421 return;
00422 }
00423
00424 err = l4io_pci_disable(pdev);
00425
00426 #if DEBUG_PCI
00427 if (err)
00428 LOGdL(DEBUG_ERRORS, "disabling PCI device (%d)", err);
00429 #endif
00430 }
00431
00439 void pci_set_master(struct pci_dev *dev)
00440 {
00441 l4io_pdev_t pdev;
00442
00443 if (!(pdev=__pci_get_handle(dev)))
00444 {
00445 #if DEBUG_PCI
00446 Panic("device %p not found", dev);
00447 #endif
00448 return;
00449 }
00450
00451 l4io_pci_set_master(pdev);
00452 }
00453
00455 int pci_set_mwi(struct pci_dev *dev)
00456 {
00457 #if DEBUG_MSG
00458 LOG_Enter("%s", dev->name);
00459 #endif
00460 return -EINVAL;
00461 }
00462
00464 void pci_clear_mwi(struct pci_dev *dev)
00465 {
00466 #if DEBUG_MSG
00467 LOG_Enter("%s", dev->name);
00468 #endif
00469 }
00482 int pci_set_power_state(struct pci_dev *dev, int state)
00483 {
00484 l4io_pdev_t pdev;
00485
00486 if (!(pdev=__pci_get_handle(dev)))
00487 {
00488 #if DEBUG_PCI
00489 LOGdL(DEBUG_ERRORS, "device %p not found", dev);
00490 #endif
00491 return PCIBIOS_DEVICE_NOT_FOUND;
00492 }
00493
00494 return l4io_pci_set_pm(pdev, state);
00495 }
00496
00498 int pci_enable_wake(struct pci_dev *dev, u32 state, int enable)
00499 {
00500 #if DEBUG_MSG
00501 LOG_Enter("%s", dev->name);
00502 #endif
00503 return -EINVAL;
00504 }
00505
00507 int pci_save_state(struct pci_dev *dev, u32 *buffer)
00508 {
00509 #if DEBUG_MSG
00510 LOG_Enter("%s", dev->name);
00511 #endif
00512 return -EINVAL;
00513 }
00514
00516 int pci_restore_state(struct pci_dev *dev, u32 *buffer)
00517 {
00518 #if DEBUG_MSG
00519 LOG_Enter("%s", dev->name);
00520 #endif
00521 return -EINVAL;
00522 }
00523
00538 void pci_release_region(struct pci_dev *pdev, int bar)
00539 {
00540 if (pci_resource_len(pdev, bar) == 0)
00541 return;
00542 if (pci_resource_flags(pdev, bar) & IORESOURCE_IO)
00543 release_region(pci_resource_start(pdev, bar),
00544 pci_resource_len(pdev, bar));
00545 else
00546 if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM)
00547 release_mem_region(pci_resource_start(pdev, bar),
00548 pci_resource_len(pdev, bar));
00549 }
00550
00564 int pci_request_region(struct pci_dev *pdev, int bar, char *res_name)
00565 {
00566 if (pci_resource_len(pdev, bar) == 0)
00567 return 0;
00568
00569 if (pci_resource_flags(pdev, bar) & IORESOURCE_IO)
00570 {
00571 if (!request_region(pci_resource_start(pdev, bar),
00572 pci_resource_len(pdev, bar), res_name))
00573 goto err_out;
00574 }
00575 else if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM)
00576 {
00577 if (!request_mem_region(pci_resource_start(pdev, bar),
00578 pci_resource_len(pdev, bar), res_name))
00579 goto err_out;
00580 }
00581
00582 return 0;
00583
00584 err_out:
00585 printk(KERN_WARNING "PCI: Unable to reserve %s region #%d:%lx@%lx for device %s\n",
00586 pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem",
00587 bar + 1,
00588 pci_resource_len(pdev, bar), pci_resource_start(pdev, bar),
00589 pdev->slot_name);
00590 return -EBUSY;
00591 }
00592
00593
00601 void pci_release_regions(struct pci_dev *pdev)
00602 {
00603 int i;
00604
00605 for (i = 0; i < 6; i++)
00606 pci_release_region(pdev, i);
00607 }
00608
00621 int pci_request_regions(struct pci_dev *pdev, char *res_name)
00622 {
00623 int i;
00624
00625 for (i = 0; i < 6; i++)
00626 if (pci_request_region(pdev, i, res_name))
00627 goto err_out;
00628 return 0;
00629
00630 err_out:
00631 printk(KERN_WARNING "PCI: Unable to reserve %s region #%d:%lx@%lx for device %s\n",
00632 pci_resource_flags(pdev, i) & IORESOURCE_IO ? "I/O" : "mem",
00633 i + 1,
00634 pci_resource_len(pdev, i), pci_resource_start(pdev, i),
00635 pdev->slot_name);
00636 while(--i >= 0)
00637 pci_release_region(pdev, i);
00638
00639 return -EBUSY;
00640 }
00641
00655 struct pci_pool
00656 {
00657 struct list_head page_list;
00658 spinlock_t lock;
00659 size_t blocks_per_page;
00660 size_t size;
00661 int flags;
00662 struct pci_dev *dev;
00663 size_t allocation;
00664 char name [32];
00665 wait_queue_head_t waitq;
00666 };
00667
00669 struct pci_page
00670 {
00671 struct list_head page_list;
00672 void *vaddr;
00673 dma_addr_t dma;
00674 unsigned long bitmap [0];
00675 };
00676
00677 #define POOL_TIMEOUT_JIFFIES ((100 * HZ) / 1000)
00678 #define POOL_POISON_BYTE 0xa7
00679
00680
00681
00704 struct pci_pool * pci_pool_create(const char *name, struct pci_dev *pdev,
00705 size_t size, size_t align, size_t allocation,
00706 int flags)
00707 {
00708 struct pci_pool *retval;
00709
00710 if (align == 0)
00711 align = 1;
00712 if (size == 0)
00713 return 0;
00714 else if (size < align)
00715 size = align;
00716 else if ((size % align) != 0)
00717 {
00718 size += align + 1;
00719 size &= ~(align - 1);
00720 }
00721
00722 if (allocation == 0)
00723 {
00724 if (PAGE_SIZE < size)
00725 allocation = size;
00726 else
00727 allocation = PAGE_SIZE;
00728
00729 }
00730 else if (allocation < size)
00731 return 0;
00732
00733 if (!(retval = kmalloc(sizeof *retval, flags)))
00734 return retval;
00735
00736 #ifdef CONFIG_PCIPOOL_DEBUG
00737 flags |= SLAB_POISON;
00738 #endif
00739
00740 strncpy(retval->name, name, sizeof retval->name);
00741 retval->name [sizeof retval->name - 1] = 0;
00742
00743 retval->dev = pdev;
00744 INIT_LIST_HEAD(&retval->page_list);
00745 spin_lock_init(&retval->lock);
00746 retval->size = size;
00747 retval->flags = flags;
00748 retval->allocation = allocation;
00749 retval->blocks_per_page = allocation / size;
00750 init_waitqueue_head(&retval->waitq);
00751
00752 #ifdef CONFIG_PCIPOOL_DEBUG
00753 printk(KERN_DEBUG "pcipool create %s/%s size %d, %d/page(%d alloc)\n",
00754 pdev ? pdev->slot_name : NULL, retval->name, size,
00755 retval->blocks_per_page, allocation);
00756 #endif
00757
00758 return retval;
00759 }
00760
00762 static struct pci_page * pool_alloc_page(struct pci_pool *pool, int mem_flags)
00763 {
00764 struct pci_page *page;
00765 int mapsize;
00766
00767 mapsize = pool->blocks_per_page;
00768 mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG;
00769 mapsize *= sizeof(long);
00770
00771 page = (struct pci_page *) kmalloc(mapsize + sizeof *page, mem_flags);
00772 if (!page)
00773 return 0;
00774 page->vaddr = pci_alloc_consistent(pool->dev, pool->allocation, &page->dma);
00775 if (page->vaddr)
00776 {
00777 memset(page->bitmap, 0xff, mapsize);
00778 if (pool->flags & SLAB_POISON)
00779 memset(page->vaddr, POOL_POISON_BYTE, pool->allocation);
00780 list_add(&page->page_list, &pool->page_list);
00781 }
00782 else
00783 {
00784 kfree(page);
00785 page = 0;
00786 }
00787 return page;
00788 }
00789
00790
00792 static inline int is_page_busy(int blocks, unsigned long *bitmap)
00793 {
00794 while (blocks > 0)
00795 {
00796 if (*bitmap++ != ~0UL)
00797 return 1;
00798 blocks -= BITS_PER_LONG;
00799 }
00800 return 0;
00801 }
00802
00804 static void pool_free_page(struct pci_pool *pool, struct pci_page *page)
00805 {
00806 dma_addr_t dma = page->dma;
00807
00808 if (pool->flags & SLAB_POISON)
00809 memset(page->vaddr, POOL_POISON_BYTE, pool->allocation);
00810 pci_free_consistent(pool->dev, pool->allocation, page->vaddr, dma);
00811 list_del(&page->page_list);
00812 kfree(page);
00813 }
00814
00815
00824 void pci_pool_destroy(struct pci_pool *pool)
00825 {
00826 unsigned long flags;
00827
00828 #ifdef CONFIG_PCIPOOL_DEBUG
00829 printk(KERN_DEBUG "pcipool destroy %s/%s\n",
00830 pool->dev ? pool->dev->slot_name : NULL,
00831 pool->name);
00832 #endif
00833
00834 spin_lock_irqsave(&pool->lock, flags);
00835 while (!list_empty(&pool->page_list))
00836 {
00837 struct pci_page *page;
00838 page = list_entry(pool->page_list.next,
00839 struct pci_page, page_list);
00840 if (is_page_busy(pool->blocks_per_page, page->bitmap))
00841 {
00842 printk(KERN_ERR "pci_pool_destroy %s/%s, %p busy\n",
00843 pool->dev ? pool->dev->slot_name : NULL,
00844 pool->name, page->vaddr);
00845
00846 list_del(&page->page_list);
00847 kfree(page);
00848 }
00849 else pool_free_page(pool, page);
00850 }
00851 spin_unlock_irqrestore(&pool->lock, flags);
00852 kfree(pool);
00853 }
00854
00855
00867 void * pci_pool_alloc(struct pci_pool *pool, int mem_flags, dma_addr_t *handle)
00868 {
00869 unsigned long flags;
00870 struct list_head *entry;
00871 struct pci_page *page;
00872 int map, block;
00873 size_t offset;
00874 void *retval;
00875
00876 restart:
00877 spin_lock_irqsave(&pool->lock, flags);
00878 list_for_each(entry, &pool->page_list)
00879 {
00880 int i;
00881 page = list_entry(entry, struct pci_page, page_list);
00882
00883 for (map = 0, i = 0; i < pool->blocks_per_page; i += BITS_PER_LONG, map++)
00884 {
00885 if (page->bitmap [map] == 0)
00886 continue;
00887 block = ffz(~ page->bitmap [map]);
00888 if ((i + block) < pool->blocks_per_page)
00889 {
00890 clear_bit(block, &page->bitmap [map]);
00891 offset = (BITS_PER_LONG * map) + block;
00892 offset *= pool->size;
00893 goto ready;
00894 }
00895 }
00896 }
00897 if (!(page = pool_alloc_page(pool, mem_flags)))
00898 {
00899 if (mem_flags == SLAB_KERNEL)
00900 {
00901 DECLARE_WAITQUEUE(wait, current);
00902
00903 current->state = TASK_INTERRUPTIBLE;
00904 add_wait_queue(&pool->waitq, &wait);
00905 spin_unlock_irqrestore(&pool->lock, flags);
00906
00907 schedule_timeout(POOL_TIMEOUT_JIFFIES);
00908
00909 current->state = TASK_RUNNING;
00910 remove_wait_queue(&pool->waitq, &wait);
00911 goto restart;
00912 }
00913 retval = 0;
00914 goto done;
00915 }
00916
00917 clear_bit(0, &page->bitmap [0]);
00918 offset = 0;
00919 ready:
00920 retval = offset + page->vaddr;
00921 *handle = offset + page->dma;
00922 done:
00923 spin_unlock_irqrestore(&pool->lock, flags);
00924 return retval;
00925 }
00926
00927
00929 static struct pci_page *
00930 pool_find_page(struct pci_pool *pool, dma_addr_t dma)
00931 {
00932 unsigned long flags;
00933 struct list_head *entry;
00934 struct pci_page *page;
00935
00936 spin_lock_irqsave(&pool->lock, flags);
00937 list_for_each(entry, &pool->page_list)
00938 {
00939 page = list_entry(entry, struct pci_page, page_list);
00940 if (dma < page->dma)
00941 continue;
00942 if (dma < (page->dma + pool->allocation))
00943 goto done;
00944 }
00945 page = 0;
00946 done:
00947 spin_unlock_irqrestore(&pool->lock, flags);
00948 return page;
00949 }
00950
00951
00960 void
00961 pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma)
00962 {
00963 struct pci_page *page;
00964 unsigned long flags;
00965 int map, block;
00966
00967 if ((page = pool_find_page (pool, dma)) == 0)
00968 {
00969 printk(KERN_ERR "pci_pool_free %s/%s, %p/%x (bad dma)\n",
00970 pool->dev ? pool->dev->slot_name : NULL,
00971 pool->name, vaddr, (int) (dma & 0xffffffff));
00972 return;
00973 }
00974 #ifdef CONFIG_PCIPOOL_DEBUG
00975 if (((dma - page->dma) + (void *)page->vaddr) != vaddr)
00976 {
00977 printk(KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%x\n",
00978 pool->dev ? pool->dev->slot_name : NULL,
00979 pool->name, vaddr, (int) (dma & 0xffffffff));
00980 return;
00981 }
00982 #endif
00983
00984 block = dma - page->dma;
00985 block /= pool->size;
00986 map = block / BITS_PER_LONG;
00987 block %= BITS_PER_LONG;
00988
00989 #ifdef CONFIG_PCIPOOL_DEBUG
00990 if (page->bitmap [map] & (1UL << block))
00991 {
00992 printk(KERN_ERR "pci_pool_free %s/%s, dma %x already free\n",
00993 pool->dev ? pool->dev->slot_name : NULL,
00994 pool->name, dma);
00995 return;
00996 }
00997 #endif
00998 if (pool->flags & SLAB_POISON)
00999 memset(vaddr, POOL_POISON_BYTE, pool->size);
01000
01001 spin_lock_irqsave(&pool->lock, flags);
01002 set_bit(block, &page->bitmap [map]);
01003 if (waitqueue_active(&pool->waitq))
01004 wake_up(&pool->waitq);
01005
01006
01007
01008
01009
01010 spin_unlock_irqrestore(&pool->lock, flags);
01011 }
01012
01018 void *pci_alloc_consistent(struct pci_dev *hwdev,
01019 size_t size, dma_addr_t * dma_handle)
01020 {
01021 void *ret;
01022 int gfp = GFP_ATOMIC;
01023
01024
01025
01026
01027
01028 ret = (void *) __get_free_pages(gfp, get_order(size));
01029
01030 if (ret != NULL)
01031 {
01032 memset(ret, 0, size);
01033 *dma_handle = virt_to_bus(ret);
01034 }
01035 LOGdL(DEBUG_PALLOC, "PCI requested pages");
01036 return ret;
01037 }
01038
01044 void pci_free_consistent(struct pci_dev *hwdev, size_t size,
01045 void *vaddr, dma_addr_t dma_handle)
01046 {
01047 free_pages((unsigned long) vaddr, get_order(size));
01048 LOGdL(DEBUG_PALLOC, "PCI released pages");
01049 }
01050
01051
01052 int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
01053 {
01054 dev->dma_mask = mask;
01055
01056 return 0;
01057 }
01058
01072
01073 int pci_read_config_byte(struct pci_dev *dev, int pos, l4_uint8_t * val)
01074 {
01075 int err;
01076 l4io_pdev_t pdev;
01077
01078 if (!(pdev=__pci_get_handle(dev)))
01079 {
01080 #if DEBUG_PCI
01081 LOG_Error("device %p not found", dev);
01082 #endif
01083 return PCIBIOS_DEVICE_NOT_FOUND;
01084 }
01085
01086 err = l4io_pci_readb_cfg(pdev, pos, val);
01087
01088 #if DEBUG_PCI
01089 if (err)
01090 LOG_Error("reading PCI config register (%d)", err);
01091 #endif
01092
01093 return err ? -EIO : 0;
01094 }
01095
01105 int pci_read_config_word(struct pci_dev *dev, int pos, l4_uint16_t * val)
01106 {
01107 int err;
01108 l4io_pdev_t pdev;
01109
01110 if (!(pdev=__pci_get_handle(dev)))
01111 {
01112 #if DEBUG_PCI
01113 LOG_Error("device %p not found", dev);
01114 #endif
01115 return PCIBIOS_DEVICE_NOT_FOUND;
01116 }
01117
01118 err = l4io_pci_readw_cfg(pdev, pos, val);
01119
01120 #if DEBUG_PCI
01121 if (err)
01122 LOG_Error("reading PCI config register (%d)", err);
01123 #endif
01124
01125 return err ? -EIO : 0;
01126 }
01127
01137 int pci_read_config_dword(struct pci_dev *dev, int pos, l4_uint32_t * val)
01138 {
01139 int err;
01140 l4io_pdev_t pdev;
01141
01142 if (!(pdev=__pci_get_handle(dev)))
01143 {
01144 #if DEBUG_PCI
01145 LOG_Error("device %p not found", dev);
01146 #endif
01147 return PCIBIOS_DEVICE_NOT_FOUND;
01148 }
01149
01150 err = l4io_pci_readl_cfg(pdev, pos, val);
01151
01152 #if DEBUG_PCI
01153 if (err)
01154 LOG_Error("reading PCI config register (%d)", err);
01155 #endif
01156
01157 return err ? -EIO : 0;
01158 }
01159
01169 int pci_write_config_byte(struct pci_dev *dev, int pos, l4_uint8_t val)
01170 {
01171 int err;
01172 l4io_pdev_t pdev;
01173
01174 if (!(pdev=__pci_get_handle(dev)))
01175 {
01176 #if DEBUG_PCI
01177 LOG_Error("device %p not found", dev);
01178 #endif
01179 return PCIBIOS_DEVICE_NOT_FOUND;
01180 }
01181
01182 err = l4io_pci_writeb_cfg(pdev, pos, val);
01183
01184 #if DEBUG_PCI
01185 if (err)
01186 LOG_Error("writing PCI config register (%d)", err);
01187 #endif
01188
01189 return err ? -EIO : 0;
01190 }
01191
01201 int pci_write_config_word(struct pci_dev *dev, int pos, l4_uint16_t val)
01202 {
01203 int err;
01204 l4io_pdev_t pdev;
01205
01206 if (!(pdev=__pci_get_handle(dev)))
01207 {
01208 #if DEBUG_PCI
01209 LOG_Error("device %p not found", dev);
01210 #endif
01211 return PCIBIOS_DEVICE_NOT_FOUND;
01212 }
01213
01214 err = l4io_pci_writew_cfg(pdev, pos, val);
01215
01216 #if DEBUG_PCI
01217 if (err)
01218 LOG_Error("writing PCI config register (%d)", err);
01219 #endif
01220
01221 return err ? -EIO : 0;
01222 }
01223
01233 int pci_write_config_dword(struct pci_dev *dev, int pos, l4_uint32_t val)
01234 {
01235 int err;
01236 l4io_pdev_t pdev;
01237
01238 if (!(pdev=__pci_get_handle(dev)))
01239 {
01240 #if DEBUG_PCI
01241 LOG_Error("device %p not found", dev);
01242 #endif
01243 return PCIBIOS_DEVICE_NOT_FOUND;
01244 }
01245
01246 err = l4io_pci_writel_cfg(pdev, pos, val);
01247
01248 #if DEBUG_PCI
01249 if (err)
01250 LOG_Error("writing PCI config register (%d)", err);
01251 #endif
01252
01253 return err ? -EIO : 0;
01254 }
01255
01261 #if 0
01262
01264 int pcibios_find_class(unsigned int class, unsigned short index,
01265 unsigned char *bus, unsigned char *devfn)
01266 {
01267 const struct pci_dev *dev = NULL;
01268 int cnt = 0;
01269
01270 while ((dev = pci_find_class(class, dev)))
01271 if (index == cnt++)
01272 {
01273 *bus = dev->bus->number;
01274 *devfn = dev->devfn;
01275 return PCIBIOS_SUCCESSFUL;
01276 }
01277
01278 return PCIBIOS_DEVICE_NOT_FOUND;
01279 }
01280 #endif
01281
01284 int pcibios_find_device(unsigned short vendor, unsigned short device,
01285 unsigned short index, unsigned char *bus,
01286 unsigned char *devfn)
01287 {
01288 const struct pci_dev *dev = NULL;
01289 int cnt = 0;
01290
01291 while ((dev = pci_find_device(vendor, device, dev)))
01292 if (index == cnt++)
01293 {
01294 *bus = dev->bus->number;
01295 *devfn = dev->devfn;
01296 return PCIBIOS_SUCCESSFUL;
01297 }
01298
01299 return PCIBIOS_DEVICE_NOT_FOUND;
01300 }
01301
01304 #define PCI_OP(rw,size,type) \
01305 int pcibios_##rw##_config_##size (unsigned char bus, unsigned char dev_fn, \
01306 unsigned char where, unsigned type val) \
01307 { \
01308 struct pci_dev *dev = pci_find_slot(bus, dev_fn); \
01309 if (!dev) return PCIBIOS_DEVICE_NOT_FOUND; \
01310 return pci_##rw##_config_##size(dev, where, val); \
01311 }
01312
01313 PCI_OP(read, byte, char *)
01314 PCI_OP(read, word, short *)
01315 PCI_OP(read, dword, int *)
01316 PCI_OP(write, byte, char)
01317 PCI_OP(write, word, short)
01318 PCI_OP(write, dword, int)
01319
01330 int l4dde_pci_init(void)
01331 {
01332 struct pci_dev *dev = NULL;
01333 int err, i;
01334 l4io_pdev_t start = 0;
01335 l4io_pci_dev_t new;
01336
01337 if (_initialized)
01338 return -L4_ESKIPPED;
01339
01340
01341 if (l4sigma0_kip_kernel_is_ux())
01342 return 0;
01343
01344
01345 INIT_LIST_HEAD(&pcibus.devices);
01346
01347
01348 for (;;)
01349 {
01350 if (dev && !(start=__pci_get_handle((struct pci_dev*)dev)))
01351 {
01352 #if DEBUG_PCI
01353 Panic("device %p not found -- Maybe you have to setup PCI_DEVICES"
01354 "properly (default is 12 devices maximum).", dev);
01355 #endif
01356 return -L4_EUNKNOWN;
01357 }
01358
01359 err = l4io_pci_find_device(PCI_ANY_ID, PCI_ANY_ID, start, &new);
01360
01361 if (err)
01362 {
01363 if (err == -L4_ENOTFOUND) break;
01364 #if DEBUG_PCI
01365 LOG_Error("locate PCI device (%d)", err);
01366 #endif
01367 return err;
01368 }
01369
01370
01371 for (i=0; i < PCI_DEVICES; i++)
01372 if (!pcidevs[i].l4)
01373 break;
01374 if (i == PCI_DEVICES)
01375 {
01376 #if DEBUG_PCI
01377 Panic("all PCI device slots occupied");
01378 #endif
01379 return -L4_EUNKNOWN;
01380 }
01381
01382
01383 __pci_io_to_linux(&new, &pcidevs[i].linus);
01384 pcidevs[i].l4 = new.handle;
01385
01386 dev = &pcidevs[i].linus;
01387 }
01388
01389 ++_initialized;
01390 return 0;
01391 }