Re: Tundra Tsi148 PCIX-VME Linux Driver Analysis

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Aug 05, 2008 at 04:23:10PM +0400, Michael Kolesov wrote:
> Hello!
> 
> I'm writing QNX6 Tundra Tsi148 VME manager. And currently I'm based on
> Tsi148 linux driver.
> I have some questions about pci-relative function calls.

To start with, have you read Documentation/pci.txt ?

> So. In Tundra spec there is requestment of :
> "STAL (Start Address Lower): This field determines the start address of a particular memory
> area on the PCI/X bus which is used to access VMEbus resources. The value of this field is
> compared with A31-A16 of the PCI/X bus address"
> Please see source code of this part in linux driver,with comments
> bellow:
> (full source can be found on http://www-zeuthen.desy.de/pitz/control_doc/MVME6100/Tsi148driver.tar)
> //----------------------------------------------------------------------------
> //  vmeSetOutBound
> //    Set attributes of an outbound window.
> //----------------------------------------------------------------------------
> int
> vmeSetOutBound( vmeOutWindowCfg_t *vmeOut)
> {
>   int windowNbr = vmeOut->windowNbr;
>   unsigned int existingSize;
> 
>   if(vmepcimem == 0)
>     return(-ENOMEM);
>   if(vmeOut->windowSizeL == 0)
>     return(-EINVAL);
> 
>   // Allocate and map PCI memory space for this window.
>   existingSize = out_resource[windowNbr].end - out_resource[windowNbr].start;
>   if(existingSize != vmeOut->windowSizeL){
>     if(existingSize != 0){
>       iounmap((char *)out_image_va[windowNbr]);
>       release_resource(&out_resource[windowNbr]);
>       memset(&out_resource[windowNbr], 0, sizeof(struct resource));
>     }
>     if(allocate_resource(vmepcimem, &out_resource[windowNbr], 
>          vmeOut->windowSizeL, 0, 0xFFFFFFFF, 0x10000, 0,0)) {
>          printk("allocation failed for 0x%x-0x%x (0x%x)\n", out_resource[windowNbr].start, 
>                     out_resource[windowNbr].end, vmeOut->windowSizeL);
>          return(-ENOMEM);
>     }
> 
>         out_image_va[windowNbr] = 
>       (int )ioremap(out_resource[windowNbr].start, vmeOut->windowSizeL);
>     if(out_image_va[windowNbr] == 0){
>          release_resource(&out_resource[windowNbr]);
>          memset(&out_resource[windowNbr], 0, sizeof(struct resource));
>          return(-ENOMEM);
>     }
>   }
> 
>   vmeOut->pciBusAddrL = out_resource[windowNbr].start 
>                         - pci_bus_mem_base_phys(vmechip_bus);
> 
>   switch(vmechip_devid) {
>     case PCI_DEVICE_ID_TUNDRA_CA91C042:
>       return(uniSetOutBound(vmeOut));
>       break;
>     case PCI_DEVICE_ID_TUNDRA_TEMPE:
>       return(tempeSetOutBound(vmeOut));
>       break;
>   }
>   return(-ENODEV);
> }
> 
> 
> 
> In linux code I see three main functions doing spec's requirements
> 
> 
> 1. allocate_resource
> 
> allocate_resource(vmepcimem, &out_resource[windowNbr],
>          vmeOut->windowSizeL, 0, 0xFFFFFFFF, 0x10000, 0,0)

drivers should generally not need to directly call this.
See pci.txt for the pci_resource interfaces.

> vmepcimem  - is 'struct resource' and before it was
> assigned by pci_find_parent_resource(vme_pci_dev, &pcimemres), where
> vme_pci_dev is Tundra Tsi148 pci_dev structure.
> 
> windowSizeL - size of needed memory window
> 
> out_resource is 'struct resource' too, for new mem area.
> -----------
> Where out_resource's start and end fields will be?
> My opinion, right after Tsi148 PCI address space region.
> What allocate_resource realy do in linux?
> Why we just can't do mmap-like function with pci-address, as example?

"pci-address" might not be 1:1 with the "host bus" address that the CPU
should be using. e.g. MMIO 0x10000 on the PCI bus might be accessed through
0x8 0010 0000 host physical address (assumes 64-bit arch).


> -----------
> 
> 2. ioremap
> 
> out_image_va[windowNbr] =
>       (int )ioremap(out_resource[windowNbr].start, vmeOut->windowSizeL);
> 
> out_image_va - virtual address of previously allocated mem space,
> throught which we can access new allocated space.
> 
> I read, it used for making special kernel virtual space address, and
> it maps high PCI addresses.
> 
> 3. pci_bus_mem_base_phys
> 
>  vmeOut->pciBusAddrL = out_resource[windowNbr].start
>                         - pci_bus_mem_base_phys(vmechip_bus);
> 
> vmechip_bus == 0.
> --------------
> So we can get start address of PCI range, right?

Yes, but unless the device is doing Peer-to-Peer transfers on the PCI bus,
the driver should be using the resource_start() values. 

> -------------
> 
> //////////////////////////
> 
> Please correct me, if I got wrong understanding of functions above.

hth,
grant

> 
> With Best Regards,
> Michael Kolesov
> software developer
> CBD BC, Saint-Petersburg, Russia
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux