2014-05-01 20 views
5

Ho codice, chiamato dalla funzione sonda() del mio autista PCIe (liberamente ispirato a questo post):È necessario "abilitare" un'area di memoria PCIe in un driver Linux 3.12?

EDIT:Sulla base Andreas Bombe's risposta, ho cambiato il codice per utilizzare pci_iomap(), ma io' m ancora sperimentare il blocco del sistema

static my_pci_dev pci_dev; /* local structure */ 
static int pci_setup_region(struct pci_dev *dev) 
{ 
    int bar = 0; 

    pci_dev.physical.addr = pci_resource_start(dev, bar); 
    pci_dev.physical.size = pci_resource_len(dev, bar); 

    pci_dev.virtual.addr = pci_iomap(dev, bar, pci_dev.physical.size); 
    if (NULL == pci_dev.virtual.addr) { 
     return -ENOMEM; 
    } else { 
     pci_dev.virtual.size = pci_dev.physical.size; 
    } 
    printk(KERN_ALERT "Virtual address: %p", pci_dev.virtual.addr); 
    if (request_mem_region(pci_dev.physical.addr, pci_dev.physical.size, DEVICE_NAME) == NULL) { 
     pci_release_resources(); 
     return -EBUSY; 
    } else { 
     pci_dev.physical.allocated = 1; 
    } 

    /* Test it out! */ 
    printk(KERN_ALERT "Trying to read data.\n"); 
    printk(KERN_ALERT "Copied chip-id data:%08x", ioread8(pci_dev.virtual.addr)); 
    return 0; 
} 

Ma il kernel appena si blocca la chiamata a ioread8().

Sto facendo qualcosa di sbagliato? O devo guardare all'hardware?

Ecco l'output su un avvio parziale del sistema di lspci -v e cat /proc/iomem:

[email protected]:~# lspci -v 
00:00.0 PCI bridge: Altera Corporation Device e000 (rev 01) (prog-if 00 [Normal decode]) 
    Flags: fast devsel 
    Bus: primary=00, secondary=01, subordinate=01, sec-latency=0 
    I/O behind bridge: 00000000-00000fff 
    Memory behind bridge: c0000000-c00fffff 
    Prefetchable memory behind bridge: 00000000-000fffff 
    Capabilities: [50] MSI: Enable- Count=1/4 Maskable- 64bit+ 
    Capabilities: [78] Power Management version 3 
    Capabilities: [80] Express Root Port (Slot-), MSI 00 
    Capabilities: [100] Virtual Channel 
    Capabilities: [200] Vendor Specific Information: ID=1172 Rev=0 Len=044 <?> 

01:00.0 Multimedia audio controller: Altera Corporation Device e002 (rev 01) 
    Subsystem: Altera Corporation Device e002 
    Flags: fast devsel, IRQ 75 
    Memory at c0000000 (32-bit, non-prefetchable) [disabled] [size=128K] 
    Capabilities: [50] MSI: Enable- Count=1/4 Maskable- 64bit+ 
    Capabilities: [78] Power Management version 3 
    Capabilities: [80] Express Endpoint, MSI 00 
    Capabilities: [100] Virtual Channel 
    Capabilities: [200] Vendor Specific Information: ID=1172 Rev=0 Len=044 <?> 
    Kernel modules: test-pci 

La memoria viene in su [disabled]: devo attivarlo?

[email protected]:~# cat /proc/iomem 
00000000-3fffffff : System RAM 
    00008000-006fa7d3 : Kernel code 
    00754000-007d8c23 : Kernel data 
c0000000-cfffffff : ALTERA PCIE RP MEM 
    c0000000-c00fffff : PCI Bus 0000:01 
    c0000000-c001ffff : 0000:01:00.0 
d0000000-dfffffff : ALTERA PCIE RP PREF MEM 
ff200000-ff20000f : csr 
ff200010-ff20008f : vector_slave 
ff210000-ff21003f : ff210000.chipidbridge0 
ff280000-ff283fff : Cra 
ff702000-ff703fff : /soc/[email protected] 
ff704000-ff704fff : /soc/[email protected] 
ff705000-ff705fff : ff705000.spi 
ffa00000-ffa00fff : ff705000.spi 
ffb40000-ffb4fffe : /soc/[email protected] 
ffc00000-ffc00fff : c_can_platform 
ffc02000-ffc0201f : serial 
ffc04000-ffc04fff : /soc/[email protected] 
ffd02000-ffd02fff : /soc/[email protected] 
ffe01000-ffe01fff : /soc/amba/[email protected] 
fff00000-fff00fff : fff00000.spi 
ffff0000-ffffffff : /soc/[email protected] 
[email protected]:~# 

risposta

9

È assolutamente necessario abilitarlo. Questi sono i passi fondamentali: è necessario

pci_enable_device(dev); 
pci_request_regions(dev, "driver/device name"); 
bar0 = pci_iomap(dev, 0, 0); 
x = ioread(bar0 + offset); /* there you are */ 

controllo degli errori per tutti i pci_* chiamate. Se il dispositivo deve eseguire DMA, è necessario chiamare anche pci_set_master e pci_set_dma_mask.

Elaborare, scavalcando il codice del kernel PCI e direttamente l'ioremapping delle BAR potrebbe aver funzionato molto tempo fa. Non sono sicuro che sia ancora più legale nel codice attuale, ma certamente non è consigliabile.

+0

Grazie per aver spiegato l'antichità del mio codice; non si rendeva conto che c'era un'interfaccia aggiornata. +1 per 'pci_iomap()': non vedo l'ora di testarlo. – Jamie

+0

Provato il tuo suggerimento senza successo. Pensando che potrebbe essere l'hardware. – Jamie

+0

Ancora non ho provato l'interfaccia 'pci_request_regions()', scheda appesa dall'altra parte della città. – Jamie