Skip to content

Commit 73bdd73

Browse files
committed
Merge branch 'pci/doe'
- Wait up to 1 second for DOE Busy bit to clear before writing a request to the mailbox to avoid failures if the mailbox is still busy from a previous transfer (Gregory Price) * pci/doe: PCI/DOE: Poll DOE Busy bit for up to 1 second in pci_doe_send_req()
2 parents d957ff7 + 86efc62 commit 73bdd73

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

drivers/pci/doe.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ static int pci_doe_send_req(struct pci_doe_mb *doe_mb,
146146
{
147147
struct pci_dev *pdev = doe_mb->pdev;
148148
int offset = doe_mb->cap_offset;
149+
unsigned long timeout_jiffies;
149150
size_t length, remainder;
150151
u32 val;
151152
int i;
@@ -155,8 +156,19 @@ static int pci_doe_send_req(struct pci_doe_mb *doe_mb,
155156
* someone other than Linux (e.g. firmware) is using the mailbox. Note
156157
* it is expected that firmware and OS will negotiate access rights via
157158
* an, as yet to be defined, method.
159+
*
160+
* Wait up to one PCI_DOE_TIMEOUT period to allow the prior command to
161+
* finish. Otherwise, simply error out as unable to field the request.
162+
*
163+
* PCIe r6.2 sec 6.30.3 states no interrupt is raised when the DOE Busy
164+
* bit is cleared, so polling here is our best option for the moment.
158165
*/
159-
pci_read_config_dword(pdev, offset + PCI_DOE_STATUS, &val);
166+
timeout_jiffies = jiffies + PCI_DOE_TIMEOUT;
167+
do {
168+
pci_read_config_dword(pdev, offset + PCI_DOE_STATUS, &val);
169+
} while (FIELD_GET(PCI_DOE_STATUS_BUSY, val) &&
170+
!time_after(jiffies, timeout_jiffies));
171+
160172
if (FIELD_GET(PCI_DOE_STATUS_BUSY, val))
161173
return -EBUSY;
162174

0 commit comments

Comments
 (0)