Jonathan Cameron wrote: > On Mon, 23 Jan 2023 11:13:00 +0100 > Lukas Wunner <lukas@xxxxxxxxx> wrote: > > > The DOE API only allows asynchronous exchanges and forces callers to > > provide a completion callback. Yet all existing callers only perform > > synchronous exchanges. Upcoming commits for CMA (Component Measurement > > and Authentication, PCIe r6.0 sec 6.31) likewise require only > > synchronous DOE exchanges. > > > > Provide a synchronous pci_doe() API call which builds on the internal > > asynchronous machinery. > > > > Convert the internal pci_doe_discovery() to the new call. > > > > The new API allows submission of const-declared requests, necessitating > > the addition of a const qualifier in struct pci_doe_task. > > > > Tested-by: Ira Weiny <ira.weiny@xxxxxxxxx> > > Signed-off-by: Lukas Wunner <lukas@xxxxxxxxx> > > Cc: Dan Williams <dan.j.williams@xxxxxxxxx> > > Cc: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx> > > Pushing the struct down is fine by me, though I'll note we had it > pretty much like this in one of the earlier versions and got a > request to use a struct instead to wrap up all the parameters. I had the same thought but decided not to pick at that old wound... ;-) > > Let's see if experience convinces people this is the right > approach this time :) It is perhaps easier to argue > now the completion is moved down as well as we'd end up with > a messy case of some elements of the structure being set in the > caller and others inside where it is called (or some messy > wrapper structures). Been a while, but I don't think we had > such a strong argument in favour of this approach back then. I think this makes a lot of sense and is clean enough. I don't think the number of parameters is outrageous. Ira > > The const changes makes sense independent of the rest. > > Reviewed-by: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx> > > > > --- > > drivers/pci/doe.c | 65 +++++++++++++++++++++++++++++++---------- > > include/linux/pci-doe.h | 6 +++- > > 2 files changed, 55 insertions(+), 16 deletions(-) > > > > diff --git a/drivers/pci/doe.c b/drivers/pci/doe.c > > index 7451b5732044..dce6af2ab574 100644 > > --- a/drivers/pci/doe.c > > +++ b/drivers/pci/doe.c > > @@ -319,26 +319,15 @@ static int pci_doe_discovery(struct pci_doe_mb *doe_mb, u8 *index, u16 *vid, > > u32 request_pl = FIELD_PREP(PCI_DOE_DATA_OBJECT_DISC_REQ_3_INDEX, > > *index); > > u32 response_pl; > > - DECLARE_COMPLETION_ONSTACK(c); > > - struct pci_doe_task task = { > > - .prot.vid = PCI_VENDOR_ID_PCI_SIG, > > - .prot.type = PCI_DOE_PROTOCOL_DISCOVERY, > > - .request_pl = &request_pl, > > - .request_pl_sz = sizeof(request_pl), > > - .response_pl = &response_pl, > > - .response_pl_sz = sizeof(response_pl), > > - .complete = pci_doe_task_complete, > > - .private = &c, > > - }; > > int rc; > > > > - rc = pci_doe_submit_task(doe_mb, &task); > > + rc = pci_doe(doe_mb, PCI_VENDOR_ID_PCI_SIG, PCI_DOE_PROTOCOL_DISCOVERY, > > + &request_pl, sizeof(request_pl), > > + &response_pl, sizeof(response_pl)); > > if (rc < 0) > > return rc; > > > > - wait_for_completion(&c); > > - > > - if (task.rv != sizeof(response_pl)) > > + if (rc != sizeof(response_pl)) > > return -EIO; > > > > *vid = FIELD_GET(PCI_DOE_DATA_OBJECT_DISC_RSP_3_VID, response_pl); > > @@ -549,3 +538,49 @@ int pci_doe_submit_task(struct pci_doe_mb *doe_mb, struct pci_doe_task *task) > > return 0; > > } > > EXPORT_SYMBOL_GPL(pci_doe_submit_task); > > + > > +/** > > + * pci_doe() - Perform Data Object Exchange > > + * > > + * @doe_mb: DOE Mailbox > > + * @vendor: Vendor ID > > + * @type: Data Object Type > > + * @request: Request payload > > + * @request_sz: Size of request payload (bytes) > > + * @response: Response payload > > + * @response_sz: Size of response payload (bytes) > > + * > > + * Submit @request to @doe_mb and store the @response. > > + * The DOE exchange is performed synchronously and may therefore sleep. > > + * > > + * RETURNS: Length of received response or negative errno. > > + * Received data in excess of @response_sz is discarded. > > + * The length may be smaller than @response_sz and the caller > > + * is responsible for checking that. > > + */ > > +int pci_doe(struct pci_doe_mb *doe_mb, u16 vendor, u8 type, > > + const void *request, size_t request_sz, > > + void *response, size_t response_sz) > > +{ > > + DECLARE_COMPLETION_ONSTACK(c); > > + struct pci_doe_task task = { > > + .prot.vid = vendor, > > + .prot.type = type, > > + .request_pl = request, > > + .request_pl_sz = request_sz, > > + .response_pl = response, > > + .response_pl_sz = response_sz, > > + .complete = pci_doe_task_complete, > > + .private = &c, > > + }; > > + int rc; > > + > > + rc = pci_doe_submit_task(doe_mb, &task); > > + if (rc) > > + return rc; > > + > > + wait_for_completion(&c); > > + > > + return task.rv; > > +} > > +EXPORT_SYMBOL_GPL(pci_doe); > > diff --git a/include/linux/pci-doe.h b/include/linux/pci-doe.h > > index ed9b4df792b8..1608e1536284 100644 > > --- a/include/linux/pci-doe.h > > +++ b/include/linux/pci-doe.h > > @@ -45,7 +45,7 @@ struct pci_doe_mb; > > */ > > struct pci_doe_task { > > struct pci_doe_protocol prot; > > - u32 *request_pl; > > + const u32 *request_pl; > > size_t request_pl_sz; > > u32 *response_pl; > > size_t response_pl_sz; > > @@ -74,4 +74,8 @@ struct pci_doe_mb *pcim_doe_create_mb(struct pci_dev *pdev, u16 cap_offset); > > bool pci_doe_supports_prot(struct pci_doe_mb *doe_mb, u16 vid, u8 type); > > int pci_doe_submit_task(struct pci_doe_mb *doe_mb, struct pci_doe_task *task); > > > > +int pci_doe(struct pci_doe_mb *doe_mb, u16 vendor, u8 type, > > + const void *request, size_t request_sz, > > + void *response, size_t response_sz); > > + > > #endif >