[SPARC64]: Implement SUN4V PCI config space access.
authorDavid S. Miller <davem@sunset.davemloft.net>
Fri, 10 Feb 2006 06:20:01 +0000 (22:20 -0800)
committerDavid S. Miller <davem@sunset.davemloft.net>
Mon, 20 Mar 2006 09:12:12 +0000 (01:12 -0800)
Signed-off-by: David S. Miller <davem@davemloft.net>
arch/sparc64/kernel/pci_sun4v.c
arch/sparc64/kernel/pci_sun4v.h
arch/sparc64/kernel/pci_sun4v_asm.S

index 1d61353e264459608bead0318111bd499894562b..abd9bfb245cbc38a3b82e64ac9bc07b5be0ae194 100644 (file)
@@ -74,15 +74,47 @@ struct pci_iommu_ops pci_sun4v_iommu_ops = {
 static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
                                  int where, int size, u32 *value)
 {
-       /* XXX Implement me! XXX */
-       return 0;
+       struct pci_pbm_info *pbm = bus_dev->sysdata;
+       unsigned long devhandle = pbm->devhandle;
+       unsigned int bus = bus_dev->number;
+       unsigned int device = PCI_SLOT(devfn);
+       unsigned int func = PCI_FUNC(devfn);
+       unsigned long ret;
+
+       ret = pci_sun4v_config_get(devhandle,
+                                  HV_PCI_DEVICE_BUILD(bus, device, func),
+                                  where, size);
+       switch (size) {
+       case 1:
+               *value = ret & 0xff;
+               break;
+       case 2:
+               *value = ret & 0xffff;
+               break;
+       case 4:
+               *value = ret & 0xffffffff;
+               break;
+       };
+
+
+       return PCIBIOS_SUCCESSFUL;
 }
 
 static int pci_sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
                                   int where, int size, u32 value)
 {
-       /* XXX Implement me! XXX */
-       return 0;
+       struct pci_pbm_info *pbm = bus_dev->sysdata;
+       unsigned long devhandle = pbm->devhandle;
+       unsigned int bus = bus_dev->number;
+       unsigned int device = PCI_SLOT(devfn);
+       unsigned int func = PCI_FUNC(devfn);
+       unsigned long ret;
+
+       ret = pci_sun4v_config_put(devhandle,
+                                  HV_PCI_DEVICE_BUILD(bus, device, func),
+                                  where, size, value);
+
+       return PCIBIOS_SUCCESSFUL;
 }
 
 static struct pci_ops pci_sun4v_ops = {
index d3ac7ece4b3128962fdd009d5214e90be4970828..5c7ed2ca1505427d741a65caa8984ab4ef442e39 100644 (file)
@@ -16,5 +16,14 @@ extern unsigned long pci_sun4v_iommu_map(unsigned long devhandle,
 extern unsigned long pci_sun4v_iommu_demap(unsigned long devhandle,
                                           unsigned long tsbid,
                                           unsigned long num_ttes);
+extern unsigned long pci_sun4v_config_get(unsigned long devhandle,
+                                         unsigned long pci_device,
+                                         unsigned long config_offset,
+                                         unsigned long size);
+extern int pci_sun4v_config_put(unsigned long devhandle,
+                               unsigned long pci_device,
+                               unsigned long config_offset,
+                               unsigned long size,
+                               unsigned long data);
 
 #endif /* !(_PCI_SUN4V_H) */
index fd2fe0edf1686fe096606005b02b7ae84a005706..2f1147146abe1ba9b031074892cdd051607e35dd 100644 (file)
@@ -54,3 +54,51 @@ pci_sun4v_iommu_demap:
        ta      HV_FAST_TRAP
        retl
         mov    %o1, %o0
+
+       /* %o0: devhandle
+        * %o1: pci_device
+        * %o2: pci_config_offset
+        * %o3: size
+        *
+        * returns %o0: data
+        *
+        * If there is an error, the data will be returned
+        * as all 1's.
+        */
+       .globl  pci_sun4v_config_get
+pci_sun4v_config_get:
+       mov     %o3, %o4
+       mov     %o2, %o3
+       mov     %o1, %o2
+       mov     %o0, %o1
+       mov     HV_FAST_PCI_CONFIG_GET, %o0
+       ta      HV_FAST_TRAP
+       brnz,a,pn %o1, 1f
+        mov    -1, %o2
+1:     retl
+        mov    %o2, %o0
+
+       /* %o0: devhandle
+        * %o1: pci_device
+        * %o2: pci_config_offset
+        * %o3: size
+        * %o4: data
+        *
+        * returns %o0: status
+        *
+        * status will be zero if the operation completed
+        * successfully, else -1 if not
+        */
+       .globl  pci_sun4v_config_put
+pci_sun4v_config_put:
+       mov     %o3, %o4
+       mov     %o2, %o3
+       mov     %o1, %o2
+       mov     %o0, %o1
+       mov     HV_FAST_PCI_CONFIG_PUT, %o0
+       ta      HV_FAST_TRAP
+       brnz,a,pn %o1, 1f
+        mov    -1, %o1
+1:     retl
+        mov    %o1, %o0
+