提交 cad4f43f 编写于 作者: B Bjorn Helgaas

Merge branch 'pci/doe'

- Fix calculation of DOE length to account for the "0 means 2^18 DWORDs"
  special case (Li Ming)

* pci/doe:
  PCI/DOE: Fix maximum data object length miscalculation
...@@ -29,6 +29,9 @@ ...@@ -29,6 +29,9 @@
#define PCI_DOE_FLAG_CANCEL 0 #define PCI_DOE_FLAG_CANCEL 0
#define PCI_DOE_FLAG_DEAD 1 #define PCI_DOE_FLAG_DEAD 1
/* Max data object length is 2^18 dwords */
#define PCI_DOE_MAX_LENGTH (1 << 18)
/** /**
* struct pci_doe_mb - State for a single DOE mailbox * struct pci_doe_mb - State for a single DOE mailbox
* *
...@@ -107,6 +110,7 @@ static int pci_doe_send_req(struct pci_doe_mb *doe_mb, ...@@ -107,6 +110,7 @@ static int pci_doe_send_req(struct pci_doe_mb *doe_mb,
{ {
struct pci_dev *pdev = doe_mb->pdev; struct pci_dev *pdev = doe_mb->pdev;
int offset = doe_mb->cap_offset; int offset = doe_mb->cap_offset;
size_t length;
u32 val; u32 val;
int i; int i;
...@@ -123,15 +127,20 @@ static int pci_doe_send_req(struct pci_doe_mb *doe_mb, ...@@ -123,15 +127,20 @@ static int pci_doe_send_req(struct pci_doe_mb *doe_mb,
if (FIELD_GET(PCI_DOE_STATUS_ERROR, val)) if (FIELD_GET(PCI_DOE_STATUS_ERROR, val))
return -EIO; return -EIO;
/* Length is 2 DW of header + length of payload in DW */
length = 2 + task->request_pl_sz / sizeof(u32);
if (length > PCI_DOE_MAX_LENGTH)
return -EIO;
if (length == PCI_DOE_MAX_LENGTH)
length = 0;
/* Write DOE Header */ /* Write DOE Header */
val = FIELD_PREP(PCI_DOE_DATA_OBJECT_HEADER_1_VID, task->prot.vid) | val = FIELD_PREP(PCI_DOE_DATA_OBJECT_HEADER_1_VID, task->prot.vid) |
FIELD_PREP(PCI_DOE_DATA_OBJECT_HEADER_1_TYPE, task->prot.type); FIELD_PREP(PCI_DOE_DATA_OBJECT_HEADER_1_TYPE, task->prot.type);
pci_write_config_dword(pdev, offset + PCI_DOE_WRITE, val); pci_write_config_dword(pdev, offset + PCI_DOE_WRITE, val);
/* Length is 2 DW of header + length of payload in DW */
pci_write_config_dword(pdev, offset + PCI_DOE_WRITE, pci_write_config_dword(pdev, offset + PCI_DOE_WRITE,
FIELD_PREP(PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH, FIELD_PREP(PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH,
2 + task->request_pl_sz / length));
sizeof(u32)));
for (i = 0; i < task->request_pl_sz / sizeof(u32); i++) for (i = 0; i < task->request_pl_sz / sizeof(u32); i++)
pci_write_config_dword(pdev, offset + PCI_DOE_WRITE, pci_write_config_dword(pdev, offset + PCI_DOE_WRITE,
task->request_pl[i]); task->request_pl[i]);
...@@ -178,7 +187,10 @@ static int pci_doe_recv_resp(struct pci_doe_mb *doe_mb, struct pci_doe_task *tas ...@@ -178,7 +187,10 @@ static int pci_doe_recv_resp(struct pci_doe_mb *doe_mb, struct pci_doe_task *tas
pci_write_config_dword(pdev, offset + PCI_DOE_READ, 0); pci_write_config_dword(pdev, offset + PCI_DOE_READ, 0);
length = FIELD_GET(PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH, val); length = FIELD_GET(PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH, val);
if (length > SZ_1M || length < 2) /* A value of 0x0 indicates max data object length */
if (!length)
length = PCI_DOE_MAX_LENGTH;
if (length < 2)
return -EIO; return -EIO;
/* First 2 dwords have already been read */ /* First 2 dwords have already been read */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册