Rev 2160 | Rev 3031 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2160 | Rev 2997 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | #include |
1 | #include |
- | 2 | #include |
|
2 | #include |
3 | #include |
3 | #include |
4 | #include |
4 | #include |
5 | #include |
5 | #include |
6 | #include |
6 | #include |
7 | #include |
Line 7... | Line -... | ||
7 | - | ||
8 | static LIST_HEAD(devices); |
- | |
9 | 8 | ||
Line -... | Line 9... | ||
- | 9 | extern int pci_scan_filter(u32_t id, u32_t busnr, u32_t devfn); |
|
Line 10... | Line 10... | ||
10 | static pci_dev_t* pci_scan_device(u32_t bus, int devfn); |
10 | |
11 | 11 | static LIST_HEAD(devices); |
|
Line 12... | Line 12... | ||
12 | 12 | ||
Line 343... | Line 343... | ||
343 | return NULL; |
343 | return NULL; |
344 | } |
344 | } |
345 | }; |
345 | }; |
346 | 346 | ||
Line -... | Line 347... | ||
- | 347 | if( pci_scan_filter(id, busnr, devfn) == 0) |
|
- | 348 | return NULL; |
|
- | 349 | ||
347 | hdr = PciRead8(busnr, devfn, PCI_HEADER_TYPE); |
350 | hdr = PciRead8(busnr, devfn, PCI_HEADER_TYPE); |
Line 348... | Line 351... | ||
348 | 351 | ||
- | 352 | dev = (pci_dev_t*)kzalloc(sizeof(pci_dev_t), 0); |
|
- | 353 | if(unlikely(dev == NULL)) |
|
Line 349... | Line 354... | ||
349 | dev = (pci_dev_t*)kzalloc(sizeof(pci_dev_t), 0); |
354 | return NULL; |
Line 350... | Line -... | ||
350 | - | ||
351 | INIT_LIST_HEAD(&dev->link); |
- | |
Line 352... | Line 355... | ||
352 | 355 | ||
353 | if(unlikely(dev == NULL)) |
356 | INIT_LIST_HEAD(&dev->link); |
354 | return NULL; |
357 | |
355 | 358 | ||
Line 365... | Line 368... | ||
365 | return dev; |
368 | return dev; |
Line 366... | Line 369... | ||
366 | 369 | ||
Line -... | Line 370... | ||
- | 370 | }; |
|
- | 371 | ||
- | 372 | ||
367 | }; |
373 | |
368 | 374 | ||
369 | int pci_scan_slot(u32_t bus, int devfn) |
375 | int pci_scan_slot(u32_t bus, int devfn) |
Line 370... | Line 376... | ||
370 | { |
376 | { |
Line 403... | Line 409... | ||
403 | 409 | ||
Line 404... | Line 410... | ||
404 | return nr; |
410 | return nr; |
405 | }; |
411 | }; |
Line 406... | Line -... | ||
406 | - | ||
407 | - | ||
408 | void pci_scan_bus(u32_t bus) |
- | |
409 | { |
- | |
410 | u32_t devfn; |
- | |
411 | pci_dev_t *dev; |
- | |
412 | - | ||
413 | - | ||
414 | for (devfn = 0; devfn < 0x100; devfn += 8) |
- | |
415 | pci_scan_slot(bus, devfn); |
- | |
416 | - | ||
417 | } |
- | |
418 | - | ||
419 | int enum_pci_devices() |
- | |
420 | { |
- | |
421 | pci_dev_t *dev; |
- | |
422 | u32_t last_bus; |
- | |
423 | u32_t bus = 0 , devfn = 0; |
- | |
424 | - | ||
425 | // list_initialize(&devices); |
- | |
426 | - | ||
427 | last_bus = PciApi(1); |
- | |
428 | - | ||
429 | - | ||
430 | if( unlikely(last_bus == -1)) |
- | |
431 | return -1; |
- | |
432 | - | ||
433 | for(;bus <= last_bus; bus++) |
- | |
434 | pci_scan_bus(bus); |
- | |
435 | - | ||
436 | // for(dev = (dev_t*)devices.next; |
- | |
437 | // &dev->link != &devices; |
- | |
438 | // dev = (dev_t*)dev->link.next) |
- | |
439 | // { |
- | |
440 | // dbgprintf("PCI device %x:%x bus:%x devfn:%x\n", |
- | |
441 | // dev->pci_dev.vendor, |
- | |
442 | // dev->pci_dev.device, |
- | |
443 | // dev->pci_dev.bus, |
- | |
444 | // dev->pci_dev.devfn); |
- | |
445 | // |
- | |
446 | // } |
- | |
447 | return 0; |
- | |
448 | } |
- | |
449 | 412 | ||
Line 450... | Line 413... | ||
450 | #define PCI_FIND_CAP_TTL 48 |
413 | #define PCI_FIND_CAP_TTL 48 |
451 | 414 | ||
452 | static int __pci_find_next_cap_ttl(unsigned int bus, unsigned int devfn, |
415 | static int __pci_find_next_cap_ttl(unsigned int bus, unsigned int devfn, |
Line 511... | Line 474... | ||
511 | return pos; |
474 | return pos; |
512 | } |
475 | } |
Line 513... | Line -... | ||
513 | - | ||
514 | - | ||
515 | #if 0 |
- | |
516 | /** |
- | |
517 | * pci_set_power_state - Set the power state of a PCI device |
- | |
518 | * @dev: PCI device to be suspended |
- | |
519 | * @state: PCI power state (D0, D1, D2, D3hot, D3cold) we're entering |
- | |
520 | * |
- | |
521 | * Transition a device to a new power state, using the Power Management |
- | |
522 | * Capabilities in the device's config space. |
- | |
523 | * |
- | |
524 | * RETURN VALUE: |
- | |
525 | * -EINVAL if trying to enter a lower state than we're already in. |
- | |
526 | * 0 if we're already in the requested state. |
- | |
527 | * -EIO if device does not support PCI PM. |
- | |
528 | * 0 if we can successfully change the power state. |
- | |
529 | */ |
- | |
530 | int |
- | |
531 | pci_set_power_state(struct pci_dev *dev, pci_power_t state) |
- | |
532 | { |
- | |
533 | int pm, need_restore = 0; |
- | |
534 | u16 pmcsr, pmc; |
- | |
535 | - | ||
536 | /* bound the state we're entering */ |
- | |
537 | if (state > PCI_D3hot) |
- | |
538 | state = PCI_D3hot; |
- | |
539 | - | ||
540 | /* |
- | |
541 | * If the device or the parent bridge can't support PCI PM, ignore |
- | |
542 | * the request if we're doing anything besides putting it into D0 |
- | |
543 | * (which would only happen on boot). |
- | |
544 | */ |
- | |
545 | if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev)) |
- | |
546 | return 0; |
- | |
547 | - | ||
Line 548... | Line -... | ||
548 | /* find PCI PM capability in list */ |
- | |
549 | pm = pci_find_capability(dev, PCI_CAP_ID_PM); |
- | |
550 | - | ||
Line 551... | Line 476... | ||
551 | /* abort if the device doesn't support PM capabilities */ |
476 | |
552 | if (!pm) |
- | |
553 | return -EIO; |
- | |
- | 477 | ||
554 | 478 | ||
555 | /* Validate current state: |
- | |
556 | * Can enter D0 from any state, but if we can only go deeper |
- | |
557 | * to sleep if we're already in a low power state |
- | |
558 | */ |
479 | |
559 | if (state != PCI_D0 && dev->current_state > state) { |
- | |
560 | printk(KERN_ERR "%s(): %s: state=%d, current state=%d\n", |
480 | int enum_pci_devices() |
Line 561... | Line -... | ||
561 | __FUNCTION__, pci_name(dev), state, dev->current_state); |
- | |
562 | return -EINVAL; |
- | |
563 | } else if (dev->current_state == state) |
- | |
564 | return 0; /* we're already there */ |
- | |
565 | - | ||
566 | - | ||
567 | pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc); |
- | |
568 | if ((pmc & PCI_PM_CAP_VER_MASK) > 3) { |
- | |
569 | printk(KERN_DEBUG |
- | |
570 | "PCI: %s has unsupported PM cap regs version (%u)\n", |
- | |
571 | pci_name(dev), pmc & PCI_PM_CAP_VER_MASK); |
- | |
572 | return -EIO; |
- | |
573 | } |
- | |
574 | - | ||
575 | /* check if this device supports the desired state */ |
- | |
576 | if (state == PCI_D1 && !(pmc & PCI_PM_CAP_D1)) |
- | |
577 | return -EIO; |
- | |
578 | else if (state == PCI_D2 && !(pmc & PCI_PM_CAP_D2)) |
- | |
579 | return -EIO; |
- | |
580 | - | ||
581 | pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr); |
- | |
582 | - | ||
583 | /* If we're (effectively) in D3, force entire word to 0. |
- | |
584 | * This doesn't affect PME_Status, disables PME_En, and |
- | |
585 | * sets PowerState to 0. |
- | |
586 | */ |
- | |
587 | switch (dev->current_state) { |
- | |
588 | case PCI_D0: |
- | |
589 | case PCI_D1: |
- | |
590 | case PCI_D2: |
- | |
591 | pmcsr &= ~PCI_PM_CTRL_STATE_MASK; |
- | |
592 | pmcsr |= state; |
- | |
593 | break; |
- | |
594 | case PCI_UNKNOWN: /* Boot-up */ |
481 | { |
595 | if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot |
- | |
596 | && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) |
- | |
Line 597... | Line -... | ||
597 | need_restore = 1; |
- | |
598 | /* Fall-through: force to D0 */ |
- | |
Line 599... | Line -... | ||
599 | default: |
- | |
600 | pmcsr = 0; |
- | |
601 | break; |
- | |
602 | } |
482 | pci_dev_t *dev; |
603 | - | ||
604 | /* enter specified state */ |
483 | u32_t last_bus; |
Line 605... | Line -... | ||
605 | pci_write_config_word(dev, pm + PCI_PM_CTRL, pmcsr); |
- | |
606 | - | ||
607 | /* Mandatory power management transition delays */ |
484 | u32_t bus = 0 , devfn = 0; |
608 | /* see PCI PM 1.1 5.6.1 table 18 */ |
485 | |
609 | if (state == PCI_D3hot || dev->current_state == PCI_D3hot) |
486 | |
610 | msleep(pci_pm_d3_delay); |
487 | last_bus = PciApi(1); |
Line 611... | Line -... | ||
611 | else if (state == PCI_D2 || dev->current_state == PCI_D2) |
- | |
Line 612... | Line -... | ||
612 | udelay(200); |
- | |
613 | - | ||
- | 488 | ||
614 | /* |
489 | |
615 | * Give firmware a chance to be called, such as ACPI _PRx, _PSx |
- | |
616 | * Firmware method after native method ? |
490 | if( unlikely(last_bus == -1)) |
617 | */ |
491 | return -1; |
618 | if (platform_pci_set_power_state) |
492 | |
619 | platform_pci_set_power_state(dev, state); |
- | |
620 | 493 | for(;bus <= last_bus; bus++) |
|
621 | dev->current_state = state; |
494 | { |
622 | 495 | for (devfn = 0; devfn < 0x100; devfn += 8) |
|
623 | /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT |
- | |
624 | * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning |
496 | pci_scan_slot(bus, devfn); |
625 | * from D3hot to D0 _may_ perform an internal reset, thereby |
497 | |
Line -... | Line 498... | ||
- | 498 | ||
626 | * going to "D0 Uninitialized" rather than "D0 Initialized". |
499 | } |
627 | * For example, at least some versions of the 3c905B and the |
500 | for(dev = (pci_dev_t*)devices.next; |
628 | * 3c556B exhibit this behaviour. |
- | |
Line 629... | Line 501... | ||
629 | * |
501 | &dev->link != &devices; |
630 | * At least some laptop BIOSen (e.g. the Thinkpad T21) leave |
502 | dev = (pci_dev_t*)dev->link.next) |
631 | * devices in a D3hot state at boot. Consequently, we need to |
- | |
632 | * restore at least the BARs so that the device will be |
503 | { |
633 | * accessible to its driver. |
504 | dbgprintf("PCI device %x:%x bus:%x devfn:%x\n", |
634 | */ |
505 | dev->pci_dev.vendor, |
635 | if (need_restore) |
506 | dev->pci_dev.device, |
636 | pci_restore_bars(dev); |
507 | dev->pci_dev.busnr, |
637 | 508 | dev->pci_dev.devfn); |
|
638 | return 0; |
509 | |
639 | } |
510 | } |
640 | #endif |
- | |
641 | 511 | return 0; |
|
Line 642... | Line 512... | ||
642 | int pcibios_enable_resources(struct pci_dev *dev, int mask) |
512 | } |
643 | { |
- | |
644 | u16_t cmd, old_cmd; |
513 | |
645 | int idx; |
- | |
646 | struct resource *r; |
514 | const struct pci_device_id* find_pci_device(pci_dev_t* pdev, const struct pci_device_id *idlist) |
647 | 515 | { |
|
648 | cmd = PciRead16(dev->busnr, dev->devfn, PCI_COMMAND); |
- | |
649 | old_cmd = cmd; |
- | |
650 | for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) |
- | |
651 | { |
516 | pci_dev_t *dev; |
652 | /* Only set up the requested stuff */ |
517 | const struct pci_device_id *ent; |
653 | if (!(mask & (1 << idx))) |
- | |
654 | continue; |
- | |
655 | - | ||
656 | r = &dev->resource[idx]; |
- | |
657 | if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM))) |
- | |
658 | continue; |
- | |
659 | if ((idx == PCI_ROM_RESOURCE) && |
- | |
660 | (!(r->flags & IORESOURCE_ROM_ENABLE))) |
- | |
661 | continue; |
- | |
662 | if (!r->start && r->end) { |
- | |
663 | printk(KERN_ERR "PCI: Device %s not available " |
518 | |
664 | "because of resource %d collisions\n", |
519 | for(dev = (pci_dev_t*)devices.next; |
665 | pci_name(dev), idx); |
520 | &dev->link != &devices; |
Line -... | Line 521... | ||
- | 521 | dev = (pci_dev_t*)dev->link.next) |
|
- | 522 | { |
|
Line -... | Line 523... | ||
- | 523 | if( dev->pci_dev.vendor != idlist->vendor ) |
|
666 | return -EINVAL; |
524 | continue; |
667 | } |
525 | |
668 | if (r->flags & IORESOURCE_IO) |
526 | for(ent = idlist; ent->vendor != 0; ent++) |
Line 669... | Line -... | ||
669 | cmd |= PCI_COMMAND_IO; |
- | |
670 | if (r->flags & IORESOURCE_MEM) |
527 | { |
Line -... | Line 528... | ||
- | 528 | if(unlikely(ent->device == dev->pci_dev.device)) |
|
- | 529 | { |
|
- | 530 | pdev->pci_dev = dev->pci_dev; |
|
- | 531 | return ent; |
|
- | 532 | } |
|
671 | cmd |= PCI_COMMAND_MEMORY; |
533 | }; |
- | 534 | } |
|
672 | } |
535 | |
- | 536 | return NULL; |
|
673 | if (cmd != old_cmd) { |
537 | }; |
674 | printk("PCI: Enabling device %s (%04x -> %04x)\n", |
538 | |
- | 539 | struct pci_dev * |
|
Line -... | Line 540... | ||
- | 540 | pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from) |
|
- | 541 | { |
|
- | 542 | pci_dev_t *dev; |
|
- | 543 | ||
- | 544 | dev = (pci_dev_t*)devices.next; |
|
Line 675... | Line 545... | ||
675 | pci_name(dev), old_cmd, cmd); |
545 | |
676 | PciWrite16(dev->busnr, dev->devfn, PCI_COMMAND, cmd); |
546 | if(from != NULL) |
- | 547 | { |
|
677 | } |
548 | for(; &dev->link != &devices; |
- | 549 | dev = (pci_dev_t*)dev->link.next) |
|
- | 550 | { |
|
- | 551 | if( &dev->pci_dev == from) |
|
Line 678... | Line -... | ||
678 | return 0; |
- | |
679 | } |
- | |
680 | - | ||
681 | - | ||
682 | int pcibios_enable_device(struct pci_dev *dev, int mask) |
- | |
683 | { |
- | |
684 | int err; |
- | |
Line -... | Line 552... | ||
- | 552 | { |
|
- | 553 | dev = (pci_dev_t*)dev->link.next; |
|
- | 554 | break; |
|
- | 555 | }; |
|
- | 556 | } |
|
- | 557 | }; |
|
- | 558 | ||
- | 559 | for(; &dev->link != &devices; |
|
- | 560 | dev = (pci_dev_t*)dev->link.next) |
|
- | 561 | { |
|
- | 562 | if( dev->pci_dev.vendor != vendor ) |
|
685 | 563 | continue; |
|
686 | if ((err = pcibios_enable_resources(dev, mask)) < 0) |
564 | |
Line -... | Line 565... | ||
- | 565 | if(dev->pci_dev.device == device) |
|
- | 566 | { |
|
- | 567 | return &dev->pci_dev; |
|
- | 568 | } |
|
- | 569 | } |
|
Line -... | Line 570... | ||
- | 570 | return NULL; |
|
- | 571 | }; |
|
687 | return err; |
572 | |
688 | 573 | ||
689 | // if (!dev->msi_enabled) |
574 | struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn) |
- | 575 | { |
|
690 | // return pcibios_enable_irq(dev); |
576 | pci_dev_t *dev; |
- | 577 | ||
691 | return 0; |
578 | for(dev = (pci_dev_t*)devices.next; |
- | 579 | &dev->link != &devices; |
|
- | 580 | dev = (pci_dev_t*)dev->link.next) |
|
- | 581 | { |
|
Line -... | Line 582... | ||
- | 582 | if ( dev->pci_dev.busnr == bus && dev->pci_dev.devfn == devfn) |
|
692 | } |
583 | return &dev->pci_dev; |
- | 584 | } |
|
- | 585 | return NULL; |
|
- | 586 | } |
|
693 | 587 | ||
- | 588 | struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) |
|
- | 589 | { |
|
- | 590 | pci_dev_t *dev; |
|
- | 591 | ||
- | 592 | dev = (pci_dev_t*)devices.next; |
|
- | 593 | ||
- | 594 | if(from != NULL) |
|
- | 595 | { |
|
- | 596 | for(; &dev->link != &devices; |
|
- | 597 | dev = (pci_dev_t*)dev->link.next) |
|
Line -... | Line 598... | ||
- | 598 | { |
|
- | 599 | if( &dev->pci_dev == from) |
|
- | 600 | { |
|
- | 601 | dev = (pci_dev_t*)dev->link.next; |
|
- | 602 | break; |
|
694 | 603 | }; |
|
695 | static int do_pci_enable_device(struct pci_dev *dev, int bars) |
604 | } |
696 | { |
605 | }; |
- | 606 | ||
Line 697... | Line 607... | ||
697 | int err; |
607 | for(; &dev->link != &devices; |
698 | - | ||
699 | // err = pci_set_power_state(dev, PCI_D0); |
608 | dev = (pci_dev_t*)dev->link.next) |
- | 609 | { |
|
700 | // if (err < 0 && err != -EIO) |
610 | if( dev->pci_dev.class == class) |
701 | // return err; |
611 | { |
Line -... | Line 612... | ||
- | 612 | return &dev->pci_dev; |
|
- | 613 | } |
|
- | 614 | } |
|
- | 615 | ||
- | 616 | return NULL; |
|
Line -... | Line 617... | ||
- | 617 | } |
|
702 | err = pcibios_enable_device(dev, bars); |
618 | |
703 | // if (err < 0) |
619 | |
- | 620 | #define PIO_OFFSET 0x10000UL |
|
704 | // return err; |
621 | #define PIO_MASK 0x0ffffUL |
705 | // pci_fixup_device(pci_fixup_enable, dev); |
- | |
706 | 622 | #define PIO_RESERVED 0x40000UL |
|
707 | return 0; |
623 | |
708 | } |
624 | #define IO_COND(addr, is_pio, is_mmio) do { \ |
709 | 625 | unsigned long port = (unsigned long __force)addr; \ |
|
710 | 626 | if (port >= PIO_RESERVED) { \ |
|
711 | static int __pci_enable_device_flags(struct pci_dev *dev, |
627 | is_mmio; \ |
712 | resource_size_t flags) |
628 | } else if (port > PIO_OFFSET) { \ |
- | 629 | port &= PIO_MASK; \ |
|
713 | { |
630 | is_pio; \ |
714 | int err; |
631 | }; \ |
715 | int i, bars = 0; |
632 | } while (0) |
716 | 633 | ||
Line -... | Line 634... | ||
- | 634 | /* Create a virtual mapping cookie for an IO port range */ |
|
- | 635 | void __iomem *ioport_map(unsigned long port, unsigned int nr) |
|
- | 636 | { |
|
- | 637 | return (void __iomem *) port; |
|
Line -... | Line 638... | ||
- | 638 | } |
|
717 | // if (atomic_add_return(1, &dev->enable_cnt) > 1) |
639 | |
- | 640 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) |
|
718 | // return 0; /* already enabled */ |
641 | { |
719 | 642 | resource_size_t start = pci_resource_start(dev, bar); |
|
720 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) |
643 | resource_size_t len = pci_resource_len(dev, bar); |
- | 644 | unsigned long flags = pci_resource_flags(dev, bar); |
|
Line 721... | Line 645... | ||
721 | if (dev->resource[i].flags & flags) |
645 | |
722 | bars |= (1 << i); |
646 | if (!len || !start) |
723 | - | ||
724 | err = do_pci_enable_device(dev, bars); |
647 | return NULL; |
725 | // if (err < 0) |
648 | if (maxlen && len > maxlen) |
726 | // atomic_dec(&dev->enable_cnt); |
649 | len = maxlen; |
- | 650 | if (flags & IORESOURCE_IO) |
|
Line -... | Line 651... | ||
- | 651 | return ioport_map(start, len); |
|
727 | return err; |
652 | if (flags & IORESOURCE_MEM) { |
728 | } |
653 | return ioremap(start, len); |
729 | 654 | } |
|
- | 655 | /* What? */ |
|
- | 656 | return NULL; |
|
- | 657 | } |
|
- | 658 | ||
- | 659 | void pci_iounmap(struct pci_dev *dev, void __iomem * addr) |
|
730 | 660 | { |
|
731 | /** |
661 | IO_COND(addr, /* nothing */, iounmap(addr)); |
732 | * pci_enable_device - Initialize device before it's used by a driver. |
662 | } |
733 | * @dev: PCI device to be initialized |
663 | |
- | 664 | ||
- | 665 | struct pci_bus_region { |
|
- | 666 | resource_size_t start; |
|
- | 667 | resource_size_t end; |
|
- | 668 | }; |
|
734 | * |
669 | |
735 | * Initialize device before it's used by a driver. Ask low-level code |
670 | static inline void |
Line 736... | Line -... | ||
736 | * to enable I/O and memory. Wake up the device if it was suspended. |
- | |
737 | * Beware, this function can fail. |
- | |
Line -... | Line 671... | ||
- | 671 | pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, |
|
- | 672 | struct resource *res) |
|
- | 673 | { |
|
- | 674 | region->start = res->start; |
|
- | 675 | region->end = res->end; |
|
- | 676 | } |
|
- | 677 | ||
- | 678 | static inline int pci_read_config_dword(struct pci_dev *dev, int where, |
|
- | 679 | u32 *val) |
|
- | 680 | { |
|
- | 681 | *val = PciRead32(dev->busnr, dev->devfn, where); |
|
- | 682 | return 1; |
|
- | 683 | } |
|
- | 684 | ||
- | 685 | static inline int pci_write_config_dword(struct pci_dev *dev, int where, |
|
- | 686 | u32 val) |
|
- | 687 | { |
|
- | 688 | PciWrite32(dev->busnr, dev->devfn, where, val); |
|
- | 689 | return 1; |
|
- | 690 | } |
|
- | 691 | ||
- | 692 | static inline int pci_read_config_word(struct pci_dev *dev, int where, |
|
- | 693 | u16 *val) |
|
- | 694 | { |
|
- | 695 | *val = PciRead16(dev->busnr, dev->devfn, where); |
|
- | 696 | return 1; |
|
- | 697 | } |
|
- | 698 | ||
- | 699 | static inline int pci_write_config_word(struct pci_dev *dev, int where, |
|
- | 700 | u16 val) |
|
- | 701 | { |
|
- | 702 | PciWrite16(dev->busnr, dev->devfn, where, val); |
|
- | 703 | return 1; |
|
- | 704 | } |
|
- | 705 | ||
- | 706 | ||
- | 707 | int pci_enable_rom(struct pci_dev *pdev) |
|
- | 708 | { |
|
- | 709 | struct resource *res = pdev->resource + PCI_ROM_RESOURCE; |
|
- | 710 | struct pci_bus_region region; |
|
- | 711 | u32 rom_addr; |
|
- | 712 | ||
- | 713 | if (!res->flags) |
|
- | 714 | return -1; |
|
- | 715 | ||
- | 716 | pcibios_resource_to_bus(pdev, ®ion, res); |
|
- | 717 | pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr); |
|
- | 718 | rom_addr &= ~PCI_ROM_ADDRESS_MASK; |
|
- | 719 | rom_addr |= region.start | PCI_ROM_ADDRESS_ENABLE; |
|
- | 720 | pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr); |
|
- | 721 | return 0; |
|
- | 722 | } |
|
- | 723 | ||
- | 724 | void pci_disable_rom(struct pci_dev *pdev) |
|
- | 725 | { |
|
- | 726 | u32 rom_addr; |
|
- | 727 | pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr); |
|
- | 728 | rom_addr &= ~PCI_ROM_ADDRESS_ENABLE; |
|
- | 729 | pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr); |
|
- | 730 | } |
|
- | 731 | ||
- | 732 | /** |
|
- | 733 | * pci_get_rom_size - obtain the actual size of the ROM image |
|
- | 734 | * @pdev: target PCI device |
|
- | 735 | * @rom: kernel virtual pointer to image of ROM |
|
- | 736 | * @size: size of PCI window |
|
- | 737 | * return: size of actual ROM image |
|
- | 738 | * |
|
- | 739 | * Determine the actual length of the ROM image. |
|
- | 740 | * The PCI window size could be much larger than the |
|
Line 738... | Line 741... | ||
738 | * |
741 | * actual image size. |
739 | * Note we don't actually enable the device many times if we call |
742 | */ |
740 | * this function repeatedly (we just increment the count). |
743 | size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) |
741 | */ |
744 | { |
- | 745 | void __iomem *image; |
|
742 | int pci_enable_device(struct pci_dev *dev) |
746 | int last_image; |
743 | { |
747 | |
744 | return __pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO); |
748 | image = rom; |
745 | } |
749 | do { |
746 | 750 | void __iomem *pds; |
|
747 | 751 | /* Standard PCI ROMs start out with these bytes 55 AA */ |
|
748 | - | ||
749 | struct pci_device_id* find_pci_device(pci_dev_t* pdev, struct pci_device_id *idlist) |
- | |
750 | { |
- | |
751 | pci_dev_t *dev; |
- | |
752 | struct pci_device_id *ent; |
752 | if (readb(image) != 0x55) { |
753 | 753 | dev_err(&pdev->dev, "Invalid ROM contents\n"); |
|
754 | for(dev = (pci_dev_t*)devices.next; |
754 | break; |
755 | &dev->link != &devices; |
755 | } |
756 | dev = (pci_dev_t*)dev->link.next) |
756 | if (readb(image + 1) != 0xAA) |
Line -... | Line 757... | ||
- | 757 | break; |
|
757 | { |
758 | /* get the PCI data structure and check its signature */ |
- | 759 | pds = image + readw(image + 24); |
|
- | 760 | if (readb(pds) != 'P') |
|
758 | if( dev->pci_dev.vendor != idlist->vendor ) |
761 | break; |
759 | continue; |
762 | if (readb(pds + 1) != 'C') |
760 | 763 | break; |
|
761 | for(ent = idlist; ent->vendor != 0; ent++) |
764 | if (readb(pds + 2) != 'I') |
762 | { |
765 | break; |
- | 766 | if (readb(pds + 3) != 'R') |
|
- | 767 | break; |
|
- | 768 | last_image = readb(pds + 21) & 0x80; |
|
- | 769 | /* this length is reliable */ |
|
- | 770 | image += readw(pds + 16) * 512; |
|
- | 771 | } while (!last_image); |
|
763 | if(unlikely(ent->device == dev->pci_dev.device)) |
772 | |
764 | { |
773 | /* never return a size larger than the PCI resource window */ |
765 | pdev->pci_dev = dev->pci_dev; |
774 | /* there are known ROMs that get the size wrong */ |
766 | return ent; |
775 | return min((size_t)(image - rom), size); |
767 | } |
776 | } |
768 | }; |
777 | |
769 | } |
778 | |
770 | 779 | /** |
|
771 | return NULL; |
780 | * pci_map_rom - map a PCI ROM to kernel space |
772 | }; |
781 | * @pdev: pointer to pci device struct |
773 | 782 | * @size: pointer to receive size of pci window over ROM |
|
774 | 783 | * |
|
775 | 784 | * Return: kernel virtual pointer to image of ROM |
|
776 | /** |
- | |
777 | * pci_map_rom - map a PCI ROM to kernel space |
- | |
778 | * @pdev: pointer to pci device struct |
- | |
779 | * @size: pointer to receive size of pci window over ROM |
- | |
780 | * @return: kernel virtual pointer to image of ROM |
785 | * |
- | 786 | * Map a PCI ROM into kernel space. If ROM is boot video ROM, |
|
- | 787 | * the shadow BIOS copy will be returned instead of the |
|
- | 788 | * actual ROM. |
|
- | 789 | */ |
|
Line 781... | Line 790... | ||
781 | * |
790 | void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) |
782 | * Map a PCI ROM into kernel space. If ROM is boot video ROM, |
791 | { |
783 | * the shadow BIOS copy will be returned instead of the |
792 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; |
784 | * actual ROM. |
793 | loff_t start; |
785 | */ |
794 | void __iomem *rom; |
- | 795 | ||
Line 786... | Line 796... | ||
786 | 796 | // ENTER(); |
|
787 | #define legacyBIOSLocation 0xC0000 |
797 | |
788 | #define OS_BASE 0x80000000 |
798 | // dbgprintf("resource start %x end %x flags %x\n", |
789 | 799 | // res->start, res->end, res->flags); |
|
Line 838... | Line 848... | ||
838 | * Try to find the true size of the ROM since sometimes the PCI window |
848 | * Try to find the true size of the ROM since sometimes the PCI window |
839 | * size is much larger than the actual size of the ROM. |
849 | * size is much larger than the actual size of the ROM. |
840 | * True size is important if the ROM is going to be copied. |
850 | * True size is important if the ROM is going to be copied. |
841 | */ |
851 | */ |
842 | *size = pci_get_rom_size(rom, *size); |
852 | *size = pci_get_rom_size(pdev, rom, *size); |
843 | 853 | // LEAVE(); |
|
- | 854 | return rom; |
|
- | 855 | } |
|
- | 856 | ||
Line -... | Line 857... | ||
- | 857 | void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) |
|
844 | #endif |
858 | { |
- | 859 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; |
|
- | 860 | ||
- | 861 | if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) |
|
- | 862 | return; |
|
Line 845... | Line -... | ||
845 | - | ||
846 | unsigned char tmp[32]; |
863 | |
Line 847... | Line 864... | ||
847 | rom = NULL; |
864 | iounmap(rom); |
848 | 865 | ||
849 | dbgprintf("Getting BIOS copy from legacy VBIOS location\n"); |
866 | /* Disable again before continuing, leave enabled if pci=rom */ |
- | 867 | if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW))) |
|
- | 868 | pci_disable_rom(pdev); |
|
850 | memcpy(tmp,(char*)(OS_BASE+legacyBIOSLocation), 32); |
869 | } |
851 | *size = tmp[2] * 512; |
870 | |
852 | if (*size > 0x10000 ) |
871 | int pci_set_dma_mask(struct pci_dev *dev, u64 mask) |
- | 872 | { |
|
853 | { |
873 | dev->dma_mask = mask; |
854 | *size = 0; |
874 | |
- | 875 | return 0; |
|
- | 876 | } |
|
- | 877 | ||
- | 878 | ||
- | 879 | ||
- | 880 | static void __pci_set_master(struct pci_dev *dev, bool enable) |
|
- | 881 | { |
|
- | 882 | u16 old_cmd, cmd; |
|
- | 883 | ||
- | 884 | pci_read_config_word(dev, PCI_COMMAND, &old_cmd); |
|
855 | dbgprintf("Invalid BIOS length field\n"); |
885 | if (enable) |
856 | } |
886 | cmd = old_cmd | PCI_COMMAND_MASTER; |
- | 887 | else |
|
- | 888 | cmd = old_cmd & ~PCI_COMMAND_MASTER; |
|
- | 889 | if (cmd != old_cmd) { |
|
- | 890 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
|
- | 891 | } |
|
Line -... | Line 892... | ||
- | 892 | dev->is_busmaster = enable; |
|
- | 893 | } |
|
- | 894 | ||
- | 895 | ||
- | 896 | /* pci_set_master - enables bus-mastering for device dev |
|
- | 897 | * @dev: the PCI device to enable |
|
- | 898 | * |
|
- | 899 | * Enables bus-mastering on the device and calls pcibios_set_master() |
|
- | 900 | * to do the needed arch specific settings. |
|
857 | else |
901 | */ |
- | 902 | void pci_set_master(struct pci_dev *dev) |
|
- | 903 | { |
|
- | 904 | __pci_set_master(dev, true); |
|
- | 905 | // pcibios_set_master(dev); |
|
- | 906 | } |
|
- | 907 | ||
- | 908 | /** |
|
- | 909 | * pci_clear_master - disables bus-mastering for device dev |
|
- | 910 | * @dev: the PCI device to disable |
|
- | 911 | */ |
|
858 | rom = (void*)( OS_BASE+legacyBIOSLocation); |
912 | void pci_clear_master(struct pci_dev *dev) |
Line 859... | Line -... | ||
859 | - | ||
860 | return rom; |
913 | { |
861 | } |
914 | __pci_set_master(dev, false); |
862 | 915 | } |
|
863 | - | ||
- | 916 | ||
Line -... | Line 917... | ||
- | 917 | ||
- | 918 | static inline int pcie_cap_version(const struct pci_dev *dev) |
|
- | 919 | { |
|
- | 920 | return dev->pcie_flags_reg & PCI_EXP_FLAGS_VERS; |
|
- | 921 | } |
|
- | 922 | ||
- | 923 | static inline bool pcie_cap_has_devctl(const struct pci_dev *dev) |
|
- | 924 | { |
|
- | 925 | return true; |
|
- | 926 | } |
|
- | 927 | ||
- | 928 | static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev) |
|
- | 929 | { |
|
- | 930 | int type = pci_pcie_type(dev); |
|
- | 931 | ||
- | 932 | return pcie_cap_version(dev) > 1 || |
|
- | 933 | type == PCI_EXP_TYPE_ROOT_PORT || |
|
- | 934 | type == PCI_EXP_TYPE_ENDPOINT || |
|
- | 935 | type == PCI_EXP_TYPE_LEG_END; |
|
- | 936 | } |
|
- | 937 | ||
- | 938 | static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev) |
|
- | 939 | { |
|
- | 940 | int type = pci_pcie_type(dev); |
|
- | 941 | ||
- | 942 | return pcie_cap_version(dev) > 1 || |
|
- | 943 | type == PCI_EXP_TYPE_ROOT_PORT || |
|
- | 944 | (type == PCI_EXP_TYPE_DOWNSTREAM && |
|
- | 945 | dev->pcie_flags_reg & PCI_EXP_FLAGS_SLOT); |
|
- | 946 | } |
|
- | 947 | ||
- | 948 | static inline bool pcie_cap_has_rtctl(const struct pci_dev *dev) |
|
- | 949 | { |
|
- | 950 | int type = pci_pcie_type(dev); |
|
- | 951 | ||
- | 952 | return pcie_cap_version(dev) > 1 || |
|
- | 953 | type == PCI_EXP_TYPE_ROOT_PORT || |
|
- | 954 | type == PCI_EXP_TYPE_RC_EC; |
|
- | 955 | } |
|
- | 956 | ||
- | 957 | static bool pcie_capability_reg_implemented(struct pci_dev *dev, int pos) |
|
- | 958 | { |
|
- | 959 | if (!pci_is_pcie(dev)) |
|
- | 960 | return false; |
|
- | 961 | ||
- | 962 | switch (pos) { |
|
- | 963 | case PCI_EXP_FLAGS_TYPE: |
|
- | 964 | return true; |
|
- | 965 | case PCI_EXP_DEVCAP: |
|
- | 966 | case PCI_EXP_DEVCTL: |
|
- | 967 | case PCI_EXP_DEVSTA: |
|
- | 968 | return pcie_cap_has_devctl(dev); |
|
- | 969 | case PCI_EXP_LNKCAP: |
|
- | 970 | case PCI_EXP_LNKCTL: |
|
- | 971 | case PCI_EXP_LNKSTA: |
|
- | 972 | return pcie_cap_has_lnkctl(dev); |
|
- | 973 | case PCI_EXP_SLTCAP: |
|
- | 974 | case PCI_EXP_SLTCTL: |
|
- | 975 | case PCI_EXP_SLTSTA: |
|
- | 976 | return pcie_cap_has_sltctl(dev); |
|
- | 977 | case PCI_EXP_RTCTL: |
|
- | 978 | case PCI_EXP_RTCAP: |
|
- | 979 | case PCI_EXP_RTSTA: |
|
- | 980 | return pcie_cap_has_rtctl(dev); |
|
- | 981 | case PCI_EXP_DEVCAP2: |
|
- | 982 | case PCI_EXP_DEVCTL2: |
|
- | 983 | case PCI_EXP_LNKCAP2: |
|
- | 984 | case PCI_EXP_LNKCTL2: |
|
- | 985 | case PCI_EXP_LNKSTA2: |
|
- | 986 | return pcie_cap_version(dev) > 1; |
|
- | 987 | default: |
|
- | 988 | return false; |
|
- | 989 | } |
|
- | 990 | } |
|
- | 991 | ||
- | 992 | /* |
|
- | 993 | * Note that these accessor functions are only for the "PCI Express |
|
- | 994 | * Capability" (see PCIe spec r3.0, sec 7.8). They do not apply to the |
|
- | 995 | * other "PCI Express Extended Capabilities" (AER, VC, ACS, MFVC, etc.) |
|
- | 996 | */ |
|
- | 997 | int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val) |
|
- | 998 | { |
|
- | 999 | int ret; |
|
- | 1000 | ||
- | 1001 | *val = 0; |
|
- | 1002 | if (pos & 1) |
|
- | 1003 | return -EINVAL; |
|
- | 1004 | ||
- | 1005 | if (pcie_capability_reg_implemented(dev, pos)) { |
|
- | 1006 | ret = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val); |
|
- | 1007 | /* |
|
- | 1008 | * Reset *val to 0 if pci_read_config_word() fails, it may |
|
- | 1009 | * have been written as 0xFFFF if hardware error happens |
|
- | 1010 | * during pci_read_config_word(). |
|
- | 1011 | */ |
|
- | 1012 | if (ret) |
|
- | 1013 | *val = 0; |
|
- | 1014 | return ret; |
|
- | 1015 | } |
|
- | 1016 | ||
- | 1017 | /* |
|
- | 1018 | * For Functions that do not implement the Slot Capabilities, |
|
- | 1019 | * Slot Status, and Slot Control registers, these spaces must |
|
- | 1020 | * be hardwired to 0b, with the exception of the Presence Detect |
|
- | 1021 | * State bit in the Slot Status register of Downstream Ports, |
|
- | 1022 | * which must be hardwired to 1b. (PCIe Base Spec 3.0, sec 7.8) |
|
- | 1023 | */ |
|
- | 1024 | if (pci_is_pcie(dev) && pos == PCI_EXP_SLTSTA && |
|
- | 1025 | pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { |
|
- | 1026 | *val = PCI_EXP_SLTSTA_PDS; |
|
- | 1027 | } |
|
- | 1028 | ||
- | 1029 | return 0; |
|
- | 1030 | } |
|
- | 1031 | EXPORT_SYMBOL(pcie_capability_read_word); |
|
- | 1032 | ||
- | 1033 | int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val) |
|
- | 1034 | { |
|
- | 1035 | int ret; |
|
- | 1036 | ||
- | 1037 | *val = 0; |
|
- | 1038 | if (pos & 3) |
|
- | 1039 | return -EINVAL; |
|
- | 1040 | ||
- | 1041 | if (pcie_capability_reg_implemented(dev, pos)) { |
|
- | 1042 | ret = pci_read_config_dword(dev, pci_pcie_cap(dev) + pos, val); |
|
864 | int |
1043 | /* |
- | 1044 | * Reset *val to 0 if pci_read_config_dword() fails, it may |
|
- | 1045 | * have been written as 0xFFFFFFFF if hardware error happens |
|
- | 1046 | * during pci_read_config_dword(). |
|
- | 1047 | */ |
|
- | 1048 | if (ret) |
|
- | 1049 | *val = 0; |
|
- | 1050 | return ret; |
|
Line 865... | Line 1051... | ||
865 | pci_set_dma_mask(struct pci_dev *dev, u64 mask) |
1051 | } |
866 | { |
1052 | |
- | 1053 | if (pci_is_pcie(dev) && pos == PCI_EXP_SLTCTL && |
|
Line -... | Line 1054... | ||
- | 1054 | pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { |
|
- | 1055 | *val = PCI_EXP_SLTSTA_PDS; |
|
- | 1056 | } |
|
- | 1057 | ||
- | 1058 | return 0; |
|
- | 1059 | } |
|
- | 1060 | EXPORT_SYMBOL(pcie_capability_read_dword); |
|
- | 1061 | ||
- | 1062 | int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val) |
|
- | 1063 | { |
|
- | 1064 | if (pos & 1) |
|
- | 1065 | return -EINVAL; |
|
- | 1066 | ||
- | 1067 | if (!pcie_capability_reg_implemented(dev, pos)) |
|
- | 1068 | return 0; |
|
- | 1069 | ||
- | 1070 | return pci_write_config_word(dev, pci_pcie_cap(dev) + pos, val); |
|
- | 1071 | } |
|
- | 1072 | EXPORT_SYMBOL(pcie_capability_write_word); |
|
- | 1073 | ||
- | 1074 | int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val) |
|
- | 1075 | { |
|
- | 1076 | if (pos & 3) |