On Thu, Dec 07, 2017 at 03:41:41PM -0600, Alan Tull wrote: > On Mon, Nov 27, 2017 at 12:42 AM, Wu Hao <hao.wu@xxxxxxxxx> wrote: > > > +/* enumerate feature devices under pci device */ > > +static int cci_enumerate_feature_devs(struct pci_dev *pcidev) > > +{ > > + struct cci_drvdata *drvdata = pci_get_drvdata(pcidev); > > + struct fpga_cdev *cdev; > > + struct fpga_enum_info *info; > > + resource_size_t start, len; > > + void __iomem *base; > > + int port_num, bar, i, ret = 0; > > + u32 offset; > > + u64 v; > > + > > + /* allocate enumeration info via pci_dev */ > > + info = fpga_enum_info_alloc(&pcidev->dev); > > + if (!info) > > + return -ENOMEM; > > + > > + /* start to find Device Feature List from Bar 0 */ > > + base = cci_pci_ioremap_bar(pcidev, 0); > > + if (!base) { > > + ret = -ENOMEM; > > + goto enum_info_free_exit; > > + } > > + > > + /* > > + * PF device has FME and Ports/AFUs, and VF device only has 1 Port/AFU. > > + * check them and add related "Device Feature List" info for the next > > + * step enumeration. > > + */ > > + if (feature_is_fme(base)) { > > + start = pci_resource_start(pcidev, 0); > > + len = pci_resource_len(pcidev, 0); > > + > > + fpga_enum_info_add_dfl(info, start, len, base); > > + > > + /* > > + * find more Device Feature Lists (e.g Ports) per information > > + * indicated by FME module. > > + */ > > + v = readq(base + FME_HDR_CAP); > > + port_num = FIELD_GET(FME_CAP_NUM_PORTS, v); > > + > > + WARN_ON(port_num > MAX_FPGA_PORT_NUM); > > + > > + for (i = 0; i < port_num; i++) { > > + v = readq(base + FME_HDR_PORT_OFST(i)); > > + > > + /* skip ports which are not implemented. */ > > + if (!(v & FME_PORT_OFST_IMP)) > > + continue; > > + > > + /* > > + * add Port's Device Feature List information for next > > + * step enumeration. > > + */ > > + bar = FIELD_GET(FME_PORT_OFST_BAR_ID, v); > > + offset = FIELD_GET(FME_PORT_OFST_DFH_OFST, v); > > + base = cci_pci_ioremap_bar(pcidev, bar); > > + if (!base) > > + continue; > > + > > + start = pci_resource_start(pcidev, bar) + offset; > > + len = pci_resource_len(pcidev, bar) - offset; > > + > > + fpga_enum_info_add_dfl(info, start, len, base + offset); > > + } > > + } else if (feature_is_port(base)) { > > + start = pci_resource_start(pcidev, 0); > > + len = pci_resource_len(pcidev, 0); > > + > > + fpga_enum_info_add_dfl(info, start, len, base); > > + } else { > > + ret = -ENODEV; > > + goto enum_info_free_exit; > > + } > > + > > + /* start enumeration with prepared enumeration information */ > > + cdev = fpga_enumerate_feature_devs(info); > > Hi Hao, > > I appreciate you separating the DFL enumeration code from this PCIe > module. This made the pcie part quite small. It should work for > embedded platforms just by adding a platform device whose function is > to find the DFL structures at some address and then call these same > fpga_enum_info_add_dfl adn fpga_enumerate_feature_devs functions. Yes, I think this is the right direction as you suggested. : ) Thanks Hao > > Alan -- To unsubscribe from this list: send the line "unsubscribe linux-api" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html