#include <const.h>
#include <errno.h>
#include <arch/i386.h>
#include <arch/mem.h>
#include <kernel/clock.h>
#include <kernel/console.h>
#include <kernel/keyboard.h>
#include <kernel/kmalloc.h>
#include <kernel/pci.h>
Go to the source code of this file.
Defines | |||||||||||||
#define | PCI_CLASS_ENTRIES ( sizeof(classes)/sizeof(classes_t) ) | ||||||||||||
The amount of supported PCI classes. | |||||||||||||
Functions | |||||||||||||
uint32_t | pciRead (int bus, int dev, int func, int reg, int uint8_ts) | ||||||||||||
Read a configuration byte/word/dword from the PCI controller.
| |||||||||||||
void | pciWrite (int bus, int dev, int func, int reg, uint32_t v, int uint8_ts) | ||||||||||||
Write a configuration byte/word/dword to the PCI controller.
| |||||||||||||
uint8_t | pci_read_config_byte (int bus, int dev, int func, int reg) | ||||||||||||
Read a configuration byte from the PCI controller.
| |||||||||||||
uint16_t | pci_read_config_word (int bus, int dev, int func, int reg) | ||||||||||||
Read a configuration word from the PCI controller.
| |||||||||||||
uint32_t | pci_read_config_dword (int bus, int dev, int func, int reg) | ||||||||||||
Read a configuration double word from the PCI controller.
| |||||||||||||
void | pci_write_config_byte (int bus, int dev, int func, int reg, uint8_t val) | ||||||||||||
Write a configuration byte to the PCI controller.
| |||||||||||||
void | pci_write_config_word (int bus, int dev, int func, int reg, uint16_t val) | ||||||||||||
Write a configuration word to the PCI controller.
| |||||||||||||
void | pci_write_config_dword (int bus, int dev, int func, int reg, uint32_t val) | ||||||||||||
Write a configuration double word to the PCI controller.
| |||||||||||||
void | pci_read_irq (pci_cfg_t *cfg) | ||||||||||||
Read the IRQ line of the device if it is present.
| |||||||||||||
uint32_t | pci_size (uint32_t base, unsigned long mask) | ||||||||||||
Calculate the size of an I/O space.
| |||||||||||||
void | pci_read_bases (pci_cfg_t *cfg, int tot_bases, int rom) | ||||||||||||
Read the base addresses of the selected deivice.
| |||||||||||||
bool | pci_probe (int bus, int dev, int func, pci_cfg_t *cfg) | ||||||||||||
Probe for a PCI device.
| |||||||||||||
void | pci_set_master (pci_cfg_t *cfg) | ||||||||||||
Enable bus-mastering (aka 32-bit DMA) for a PCI device.
| |||||||||||||
int | pci_find_capability (pci_cfg_t *cfg, int cap) | ||||||||||||
Tell if a device supports a given PCI capability.
| |||||||||||||
int | pci_set_power_state (pci_cfg_t *cfg, int state) | ||||||||||||
Set a new power state for the device using the Power Management Capabilities.
| |||||||||||||
int | pcibios_enable_device_io (pci_cfg_t *cfg) | ||||||||||||
Low level function to initialize a PCI device before it's used by a driver.
| |||||||||||||
int | pci_enable_device (pci_cfg_t *cfg) | ||||||||||||
Initialize a PCI device before it's used by a driver.
| |||||||||||||
bool | pci_find_cfg (pci_cfg_t *cfg, bool enable) | ||||||||||||
Look for a device in the PCI bus and eventually enable it.
| |||||||||||||
void | pci_scan () | ||||||||||||
Scan all the PCI buses, looking for devices. If a device is found it will be enabled. | |||||||||||||
Variables | |||||||||||||
classes_t | classes [] | ||||||||||||
PCI supported classes. It is used to recognize to what class a device belongs. | |||||||||||||
unsigned int | pcibios_max_latency = 255 | ||||||||||||
SiS 5597 and 5598 require latency timer set to at most 32 to avoid lockups; otherwise default value is 255. |
Definition in file pci.c.
|
The amount of supported PCI classes.
|
|
Initialize a PCI device before it's used by a driver.
Definition at line 734 of file pci.c.
00735 { 00736 int err, pm; 00737 00738 kprintf("\n\rPowering on PCI device %d:%d:%d... ", cfg->bus, cfg->dev, cfg->func); 00739 pm = pci_set_power_state(cfg, 0); 00740 switch( pm ) 00741 { 00742 case 0: 00743 kprintf("OK!"); 00744 break; 00745 00746 case (-EIO): 00747 kprintf("\n\rDevice doesn't support Power Management Capabilities!!!"); 00748 break; 00749 00750 case (-EINVAL): 00751 kprintf("\n\rDevice is already in this power state."); 00752 break; 00753 } 00754 00755 if ((err = pcibios_enable_device_io(cfg)) < 0) 00756 return(err); 00757 return(0); 00758 } |
|
Tell if a device supports a given PCI capability.
Definition at line 563 of file pci.c.
00564 { 00565 uint16_t status; 00566 uint8_t pos, id; 00567 int ttl = 48; 00568 00569 status = pci_read_config_word(cfg->bus, cfg->dev, cfg->func, PCI_STATUS); 00570 if ( !(status & PCI_STATUS_CAP_LIST) ) 00571 return(0); 00572 00573 switch (cfg->header_type & 0x7F) 00574 { 00575 case PCI_HEADER_TYPE_NORMAL: 00576 case PCI_HEADER_TYPE_BRIDGE: 00577 pos = pci_read_config_byte(cfg->bus, cfg->dev, cfg->func, PCI_CAPABILITY_LIST); 00578 break; 00579 00580 case PCI_HEADER_TYPE_CARDBUS: 00581 pos = pci_read_config_byte(cfg->bus, cfg->dev, cfg->func, PCI_CB_CAPABILITY_LIST); 00582 break; 00583 00584 default: 00585 return(0); 00586 break; 00587 } 00588 00589 while (ttl-- && pos>=0x40) 00590 { 00591 pos &= ~3; 00592 id = pci_read_config_byte(cfg->bus, cfg->dev, cfg->func, pos+PCI_CAP_LIST_ID); 00593 if (id == 0xff) 00594 break; 00595 if (id == cap) 00596 return(pos); 00597 pos = pci_read_config_byte(cfg->bus, cfg->dev, cfg->func, pos+PCI_CAP_LIST_NEXT); 00598 } 00599 return(0); 00600 } |
|
Look for a device in the PCI bus and eventually enable it.
Definition at line 769 of file pci.c.
00770 { 00771 uint16_t bus, dev, func; 00772 pci_cfg_t *pcfg; 00773 00774 pcfg = kmalloc( sizeof(pci_cfg_t) ); 00775 00776 for (bus=0; bus<4; bus++) 00777 for (dev=0; dev<32; dev++) 00778 for (func=0; func<8; func++) 00779 { 00780 if ( pci_probe(bus, dev, func, pcfg) ) 00781 { 00782 if ( 00783 cfg->base_class == pcfg->base_class && 00784 cfg->sub_class == pcfg->sub_class && 00785 cfg->interface == pcfg->interface 00786 ) 00787 { 00788 // Device found // 00789 memcpy(cfg, pcfg, sizeof(pci_cfg_t)); 00790 // Enable the device if required // 00791 if (enable) pci_enable_device(pcfg); 00792 // Free the temporary structure // 00793 kfree(pcfg); 00794 return(TRUE); 00795 } 00796 } 00797 } 00798 // Device not found // 00799 kfree(pcfg); 00800 return(FALSE); 00801 } |
|
Probe for a PCI device.
Definition at line 467 of file pci.c.
00468 { 00469 uint32_t *temp = (uint32_t *) cfg; 00470 int i; 00471 00472 for(i=0; i<4; i++) 00473 temp[i] = pci_read_config_dword(bus, dev, func, (i << 2)); 00474 00475 if(cfg->vendor_id == 0xFFFF) return FALSE; 00476 00477 // Setup the bus, device and function number // 00478 cfg->bus = bus; 00479 cfg->dev = dev; 00480 cfg->func = func; 00481 00482 // Set the power state to unknown // 00483 cfg->current_state = 4; 00484 00485 // Identify the type of the device // 00486 switch(cfg->header_type & 0x7F) 00487 { 00488 case PCI_HEADER_TYPE_NORMAL: 00489 // --- NORMAL DEVICE --- // 00490 // Read the IRQ line // 00491 pci_read_irq(cfg); 00492 // Read the base memory and I/O addresses // 00493 pci_read_bases(cfg, 6, PCI_ROM_ADDRESS); 00494 // Read subsysem vendor and subsystem device id // 00495 cfg->subsys_vendor = pci_read_config_word(bus, dev, func, PCI_SUBSYSTEM_VENDOR_ID); 00496 cfg->subsys_device = pci_read_config_word(bus, dev, func, PCI_SUBSYSTEM_ID); 00497 break; 00498 00499 case PCI_HEADER_TYPE_BRIDGE: 00500 // --- PCI <-> PCI BRIDGE --- // 00501 pci_read_bases(cfg, 2, PCI_ROM_ADDRESS_1); 00502 break; 00503 00504 case PCI_HEADER_TYPE_CARDBUS: 00505 // --- PCI CARDBUS --- // 00506 // Read the IRQ line // 00507 pci_read_irq(cfg); 00508 // Read the base memory and I/O addresses // 00509 pci_read_bases(cfg, 1, 0); 00510 // Read subsysem vendor and subsystem device id // 00511 cfg->subsys_vendor = pci_read_config_word(bus, dev, func, PCI_CB_SUBSYSTEM_VENDOR_ID); 00512 cfg->subsys_device = pci_read_config_word(bus, dev, func, PCI_CB_SUBSYSTEM_ID); 00513 break; 00514 00515 default: 00516 // --- UNKNOW HEADER TYPE --- // 00517 break; 00518 } 00519 00520 return(TRUE); 00521 } |
|
Read the base addresses of the selected deivice.
Definition at line 394 of file pci.c.
00395 { 00396 uint32_t l, sz, reg; 00397 int i; 00398 00399 // Clear all previous bases and sizes informations // 00400 memset(cfg->base, 0, sizeof(cfg->base)); 00401 memset(cfg->size, 0, sizeof(cfg->size)); 00402 memset(cfg->type, 0, sizeof(cfg->type)); 00403 00404 // Read informations about bases and sizes // 00405 for(i=0; i<tot_bases; i++) 00406 { 00407 // Read bases and size // 00408 reg = PCI_BASE_ADDRESS_0 + (i << 2); 00409 l = pci_read_config_dword(cfg->bus, cfg->dev, cfg->func, reg); 00410 pci_write_config_dword(cfg->bus, cfg->dev, cfg->func, reg, ~0); 00411 sz = pci_read_config_dword(cfg->bus, cfg->dev, cfg->func, reg); 00412 pci_write_config_dword(cfg->bus, cfg->dev, cfg->func, reg, l); 00413 00414 // Check if informations are valid // 00415 if (!sz || sz == 0xFFFFFFFF) 00416 continue; 00417 if (l == 0xFFFFFFFF) 00418 l = 0; 00419 00420 // Store informations // 00421 if ( (l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY ) 00422 { 00423 cfg->base[i] = l & PCI_BASE_ADDRESS_MEM_MASK; 00424 cfg->size[i] = pci_size(sz, PCI_BASE_ADDRESS_MEM_MASK); 00425 cfg->type[i] = PCI_IO_RESOURCE_MEM; 00426 } 00427 else 00428 { 00429 cfg->base[i] = l & PCI_BASE_ADDRESS_IO_MASK; 00430 cfg->size[i] = pci_size(sz, PCI_BASE_ADDRESS_IO_MASK); 00431 cfg->type[i] = PCI_IO_RESOURCE_IO; 00432 } 00433 } 00434 00435 // --- ROM --- // 00436 if (rom) 00437 { 00438 // Initialize values // 00439 cfg->rom_base = 0; 00440 cfg->rom_size = 0; 00441 00442 l = pci_read_config_dword(cfg->bus, cfg->dev, cfg->func, rom); 00443 pci_write_config_dword(cfg->bus, cfg->dev, cfg->func, rom, ~PCI_ROM_ADDRESS_ENABLE); 00444 sz = pci_read_config_dword(cfg->bus, cfg->dev, cfg->func, rom); 00445 pci_write_config_dword(cfg->bus, cfg->dev, cfg->func, rom, l); 00446 if (l == 0xFFFFFFFF) 00447 l = 0; 00448 if (sz && sz != 0xFFFFFFFF) 00449 { 00450 cfg->rom_base = l & PCI_ROM_ADDRESS_MASK; 00451 sz = pci_size(sz, PCI_ROM_ADDRESS_MASK); 00452 cfg->rom_size = cfg->rom_size + (unsigned long)sz; 00453 } 00454 } 00455 } |
|
Read a configuration byte from the PCI controller.
Definition at line 279 of file pci.c.
|
|
Read a configuration double word from the PCI controller.
Definition at line 303 of file pci.c.
|
|
Read a configuration word from the PCI controller.
Definition at line 291 of file pci.c.
|
|
Read the IRQ line of the device if it is present.
Definition at line 351 of file pci.c.
00352 { 00353 unsigned char irq; 00354 00355 irq = pci_read_config_byte(cfg->bus, cfg->dev, cfg->func, PCI_INTERRUPT_PIN); 00356 if (irq) 00357 irq = pci_read_config_byte(cfg->bus, cfg->dev, cfg->func, PCI_INTERRUPT_LINE); 00358 00359 cfg->irq = irq; 00360 } |
|
Scan all the PCI buses, looking for devices. If a device is found it will be enabled.
Definition at line 806 of file pci.c.
00807 { 00808 uint16_t bus, dev, func; 00809 pci_cfg_t pcfg; 00810 int i, key; 00811 00812 for (bus=0; bus<4; bus++) 00813 for (dev = 0; dev < 32; dev++) 00814 for (func = 0; func < 8; func++) 00815 { 00816 if ( pci_probe(bus, dev, func, &pcfg) ) 00817 { 00818 set_color(WHITE); 00819 kprintf("\n\rPCI:%u:%u:%u", bus, dev, func); 00820 set_color(DEFAULT_COLOR); 00821 00822 kprintf( "\n\rVendor :%04X Device :%04X" 00823 "\n\rSubSys_Vendor:%04X SubSys_Device:%04X", 00824 pcfg.vendor_id, pcfg.device_id, pcfg.subsys_vendor, pcfg.subsys_device); 00825 kprintf( "\n\rBase_Class :%02X Sub_Class :%02X Interface :%02X", 00826 pcfg.base_class, pcfg.sub_class, pcfg.interface); 00827 00828 for (i=0;; i++) 00829 { 00830 if ( i>=PCI_CLASS_ENTRIES ) 00831 { 00832 kprintf("\n\r* Description : Unknown device!"); 00833 break; 00834 } 00835 if 00836 ( 00837 (classes[i].base_class == pcfg.base_class) && 00838 (classes[i].sub_class == pcfg.sub_class) && 00839 (classes[i].interface == pcfg.interface) 00840 ) 00841 { 00842 kprintf("\n\r* Description : %s", classes[i].name); 00843 break; 00844 } 00845 } 00846 00847 for (i=0; i<6; i++) 00848 if (pcfg.base[i]) 00849 { 00850 if (pcfg.type[i] == PCI_IO_RESOURCE_IO) 00851 kprintf("\n\r* Base Register %d IO: %#06x (%#06x)", 00852 i, pcfg.base[i], pcfg.size[i]); 00853 else 00854 kprintf("\n\r* Base Register %d MM: %#010x (%#010x)", 00855 i, pcfg.base[i] & 0xfffffff0, pcfg.size[i]); 00856 } 00857 if (pcfg.rom_base) 00858 kprintf("\n\r* Base Register ROM : %#010x (%#010x)", 00859 pcfg.rom_base, pcfg.rom_size); 00860 00861 if (pcfg.irq) 00862 kprintf("\n\r* Interrupt line: %u", pcfg.irq); 00863 00864 00865 switch(pcfg.header_type & 0x7F) 00866 { 00867 case PCI_HEADER_TYPE_NORMAL: 00868 kprintf("\n\r* Normal device"); 00869 break; 00870 00871 case PCI_HEADER_TYPE_BRIDGE: 00872 kprintf("\n\r* PCI <-> PCI bridge"); 00873 break; 00874 00875 default: 00876 kprintf("\n\r* Unknown header type"); 00877 break; 00878 } 00879 00880 // kprintf("\n\rDo you want to enable this device (Y/N)? "); 00881 pci_enable_device(&pcfg); 00882 key = kgetchar(); 00883 if ( key==CTRL_C ) return; 00884 /* 00885 key &= 0xFF; 00886 if ( key=='Y' || key=='y' ) 00887 { 00888 putchar(key); 00889 pci_enable_device(&pcfg); 00890 } 00891 else 00892 putchar('N'); 00893 */ 00894 kprintf("\n\r"); 00895 } 00896 } 00897 kprintf("\n\rPCI: finished\n\r"); 00898 } |
|
Enable bus-mastering (aka 32-bit DMA) for a PCI device.
Definition at line 529 of file pci.c.
00530 { 00531 uint16_t cmd; 00532 uint8_t lat; 00533 00534 cmd = pci_read_config_word(cfg->bus, cfg->dev, cfg->func, PCI_COMMAND); 00535 if ( !(cmd & PCI_COMMAND_MASTER) ) 00536 { 00537 kprintf("PCI: Enabling bus mastering for device in slot %d:%d:%d\n", cfg->bus, cfg->dev, cfg->func); 00538 cmd |= PCI_COMMAND_MASTER; 00539 pci_write_config_word(cfg->bus, cfg->dev, cfg->func, PCI_COMMAND, cmd); 00540 } 00541 // Check the latency time, because certain BIOSes forget to set // 00542 // it properly... // 00543 lat = pci_read_config_byte(cfg->bus, cfg->dev, cfg->func, PCI_LATENCY_TIMER); 00544 if ( lat < 16 ) 00545 lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; 00546 else if ( lat > pcibios_max_latency ) 00547 lat = pcibios_max_latency; 00548 else 00549 return; 00550 kprintf("PCI: Setting latency timer of device %d:%d:%d to %u\n", cfg->bus, cfg->dev, cfg->func, lat); 00551 pci_write_config_byte(cfg->bus, cfg->dev, cfg->func, PCI_LATENCY_TIMER, lat); 00552 } |
|
Set a new power state for the device using the Power Management Capabilities.
Definition at line 612 of file pci.c.
00613 { 00614 int pm; 00615 uint16_t pmcsr; 00616 uint16_t pmc; 00617 00618 // Bound the state to a valid range // 00619 if (state > 3) state = 3; 00620 00621 // Validate current state. // 00622 // Can enter D0 from any state, but we can't go deeper if we're // 00623 // in a low power state. // 00624 if (state > 0 && cfg->current_state > state) 00625 return(-EINVAL); 00626 else if (cfg->current_state == state) 00627 // we're already there // 00628 return(0); 00629 00630 // find PCI PM capability in list // 00631 pm = pci_find_capability(cfg, PCI_CAP_ID_PM); 00632 00633 // Abort if the device doesn't support PM capabilities // 00634 if (!pm) return(-EIO); 00635 00636 // Check if this device supports the desired state // 00637 if (state == 1 || state == 2) 00638 { 00639 pmc = pci_read_config_word(cfg->bus, cfg->dev, cfg->func, pm+PCI_PM_PMC); 00640 if ( (state == 1 && !(pmc & PCI_PM_CAP_D1)) ) 00641 return(-EIO); 00642 else if ( (state == 2 && !(pmc & PCI_PM_CAP_D2)) ) 00643 return(-EIO); 00644 } 00645 00646 // If we're in D3, force entire word to 0. // 00647 // This doesn't affect PME_Status, disables PME_En, and // 00648 // sets PowerState to 0. // 00649 if ( cfg->current_state>=3 ) 00650 pmcsr = 0; 00651 else 00652 { 00653 pmcsr = pci_read_config_word(cfg->bus, cfg->dev, cfg->func, pm+PCI_PM_CTRL); 00654 pmcsr &= ~PCI_PM_CTRL_STATE_MASK; 00655 pmcsr |= state; 00656 } 00657 00658 // Enter specified state // 00659 pci_write_config_word(cfg->bus, cfg->dev, cfg->func, pm+PCI_PM_CTRL, pmcsr); 00660 00661 // Mandatory power management transition delays // 00662 // see PCI PM 1.1 5.6.1 table 18 // 00663 if( (state == 3) || (cfg->current_state == 3) ) 00664 { 00665 // Set task state to interruptible // 00666 // LINUX do it so: // 00667 // set_current_state(TASK_UNINTERRUPTIBLE); // 00668 // schedule_timeout(HZ/100); // 00669 delay(HZ/100); 00670 } 00671 else if( (state == 2) || (cfg->current_state == 2) ) 00672 // udelay(200); 00673 delay(200); 00674 cfg->current_state = state; 00675 00676 return(0); 00677 } |
|
Calculate the size of an I/O space.
Definition at line 371 of file pci.c.
00372 { 00373 // Find the significant bits // 00374 uint32_t size = mask & base; 00375 // Get the lowest of them to find the decode size // 00376 size = size & ~(size-1); 00377 // extent = size - 1 // 00378 return(size-1); 00379 } |
|
Write a configuration byte to the PCI controller.
Definition at line 317 of file pci.c.
|
|
Write a configuration double word to the PCI controller.
Definition at line 341 of file pci.c.
|
|
Write a configuration word to the PCI controller.
Definition at line 329 of file pci.c.
|
|
Low level function to initialize a PCI device before it's used by a driver.
Definition at line 687 of file pci.c.
00688 { 00689 uint16_t cmd, old_cmd; 00690 int i; 00691 00692 kprintf("\n\rLow level enabling PCI device %d:%d:%d... ", cfg->bus, cfg->dev, cfg->func); 00693 00694 old_cmd = cmd = pci_read_config_word(cfg->bus, cfg->dev, cfg->func, PCI_COMMAND); 00695 for (i=0; i<sizeof(cfg->type); i++) 00696 if (cfg->type[i] == PCI_IO_RESOURCE_IO) 00697 // Command IO based // 00698 cmd |= PCI_COMMAND_IO; 00699 00700 if ( !(cmd & PCI_COMMAND_IO) ) 00701 { 00702 // Device is not IO-based // 00703 kprintf("\n\rDevice is not IO-based!!!"); 00704 return(-EINVAL); 00705 } 00706 00707 if ( (cfg->header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE ) 00708 { 00709 // Any PCI-to-PCI bridge must be enabled by setting // 00710 // both I/O space and memory space access bits in the // 00711 // command register. // 00712 cmd |= PCI_COMMAND_MEMORY; 00713 } 00714 00715 // Always enable bus master!!! // 00716 cmd |= PCI_COMMAND_MASTER; 00717 00718 if ( cmd!=old_cmd ) 00719 { 00720 // Set the cache line and default latency (32) // 00721 pci_write_config_word(cfg->bus, cfg->dev, cfg->func, 00722 PCI_CACHE_LINE_SIZE, (32 << 8) | (L1_CACHE_BYTES / sizeof(uint32_t))); 00723 // Enable the appropriate bits in the PCI command register // 00724 pci_write_config_word(cfg->bus, cfg->dev, cfg->func, PCI_COMMAND, cmd); 00725 kprintf("OK!"); 00726 } 00727 else 00728 kprintf("Already enabled."); 00729 return(0); 00730 } |
|
Read a configuration byte/word/dword from the PCI controller.
Definition at line 198 of file pci.c.
00199 { 00200 uint16_t base; 00201 00202 union { 00203 confadd_t c; 00204 uint32_t n; 00205 } u; 00206 00207 u.n = 0; 00208 u.c.enable = 1; 00209 u.c.rsvd = 0; 00210 u.c.bus = bus; 00211 u.c.dev = dev; 00212 u.c.func = func; 00213 u.c.reg = reg & 0xFC; 00214 00215 out32(0xCF8, u.n); 00216 base = 0xCFC + (reg & 0x03); 00217 00218 switch(uint8_ts) 00219 { 00220 case 1: return in(base); 00221 case 2: return in16(base); 00222 case 4: return in32(base); 00223 default: return 0; 00224 } 00225 } |
|
Write a configuration byte/word/dword to the PCI controller.
Definition at line 242 of file pci.c.
00243 { 00244 uint16_t base; 00245 00246 union { 00247 confadd_t c; 00248 uint32_t n; 00249 } u; 00250 00251 u.n = 0; 00252 u.c.enable = 1; 00253 u.c.rsvd = 0; 00254 u.c.bus = bus; 00255 u.c.dev = dev; 00256 u.c.func = func; 00257 u.c.reg = reg & 0xFC; 00258 00259 base = 0xCFC + (reg & 0x03); 00260 out32(0xCF8, u.n); 00261 00262 switch(uint8_ts) 00263 { 00264 case 1: out(base, (uint8_t) v); break; 00265 case 2: out16(base, (uint16_t) v); break; 00266 case 4: out32(base, v); break; 00267 } 00268 } |
|
PCI supported classes. It is used to recognize to what class a device belongs.
|
|
SiS 5597 and 5598 require latency timer set to at most 32 to avoid lockups; otherwise default value is 255.
|