@@ -76,13 +76,6 @@ struct pci_doe_protocol {
7676 * @private: Private data for the consumer
7777 * @work: Used internally by the mailbox
7878 * @doe_mb: Used internally by the mailbox
79- *
80- * The payload sizes and rv are specified in bytes with the following
81- * restrictions concerning the protocol.
82- *
83- * 1) The request_pl_sz must be a multiple of double words (4 bytes)
84- * 2) The response_pl_sz must be >= a single double word (4 bytes)
85- * 3) rv is returned as bytes but it will be a multiple of double words
8679 */
8780struct pci_doe_task {
8881 struct pci_doe_protocol prot ;
@@ -153,7 +146,7 @@ static int pci_doe_send_req(struct pci_doe_mb *doe_mb,
153146{
154147 struct pci_dev * pdev = doe_mb -> pdev ;
155148 int offset = doe_mb -> cap_offset ;
156- size_t length ;
149+ size_t length , remainder ;
157150 u32 val ;
158151 int i ;
159152
@@ -171,7 +164,7 @@ static int pci_doe_send_req(struct pci_doe_mb *doe_mb,
171164 return - EIO ;
172165
173166 /* Length is 2 DW of header + length of payload in DW */
174- length = 2 + task -> request_pl_sz / sizeof (__le32 );
167+ length = 2 + DIV_ROUND_UP ( task -> request_pl_sz , sizeof (__le32 ) );
175168 if (length > PCI_DOE_MAX_LENGTH )
176169 return - EIO ;
177170 if (length == PCI_DOE_MAX_LENGTH )
@@ -184,10 +177,21 @@ static int pci_doe_send_req(struct pci_doe_mb *doe_mb,
184177 pci_write_config_dword (pdev , offset + PCI_DOE_WRITE ,
185178 FIELD_PREP (PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH ,
186179 length ));
180+
181+ /* Write payload */
187182 for (i = 0 ; i < task -> request_pl_sz / sizeof (__le32 ); i ++ )
188183 pci_write_config_dword (pdev , offset + PCI_DOE_WRITE ,
189184 le32_to_cpu (task -> request_pl [i ]));
190185
186+ /* Write last payload dword */
187+ remainder = task -> request_pl_sz % sizeof (__le32 );
188+ if (remainder ) {
189+ val = 0 ;
190+ memcpy (& val , & task -> request_pl [i ], remainder );
191+ le32_to_cpus (& val );
192+ pci_write_config_dword (pdev , offset + PCI_DOE_WRITE , val );
193+ }
194+
191195 pci_doe_write_ctrl (doe_mb , PCI_DOE_CTRL_GO );
192196
193197 return 0 ;
@@ -207,11 +211,11 @@ static bool pci_doe_data_obj_ready(struct pci_doe_mb *doe_mb)
207211
208212static int pci_doe_recv_resp (struct pci_doe_mb * doe_mb , struct pci_doe_task * task )
209213{
214+ size_t length , payload_length , remainder , received ;
210215 struct pci_dev * pdev = doe_mb -> pdev ;
211216 int offset = doe_mb -> cap_offset ;
212- size_t length , payload_length ;
217+ int i = 0 ;
213218 u32 val ;
214- int i ;
215219
216220 /* Read the first dword to get the protocol */
217221 pci_read_config_dword (pdev , offset + PCI_DOE_READ , & val );
@@ -238,15 +242,38 @@ static int pci_doe_recv_resp(struct pci_doe_mb *doe_mb, struct pci_doe_task *tas
238242
239243 /* First 2 dwords have already been read */
240244 length -= 2 ;
241- payload_length = min (length , task -> response_pl_sz / sizeof (__le32 ));
242- /* Read the rest of the response payload */
243- for (i = 0 ; i < payload_length ; i ++ ) {
245+ received = task -> response_pl_sz ;
246+ payload_length = DIV_ROUND_UP (task -> response_pl_sz , sizeof (__le32 ));
247+ remainder = task -> response_pl_sz % sizeof (__le32 );
248+
249+ /* remainder signifies number of data bytes in last payload dword */
250+ if (!remainder )
251+ remainder = sizeof (__le32 );
252+
253+ if (length < payload_length ) {
254+ received = length * sizeof (__le32 );
255+ payload_length = length ;
256+ remainder = sizeof (__le32 );
257+ }
258+
259+ if (payload_length ) {
260+ /* Read all payload dwords except the last */
261+ for (; i < payload_length - 1 ; i ++ ) {
262+ pci_read_config_dword (pdev , offset + PCI_DOE_READ ,
263+ & val );
264+ task -> response_pl [i ] = cpu_to_le32 (val );
265+ pci_write_config_dword (pdev , offset + PCI_DOE_READ , 0 );
266+ }
267+
268+ /* Read last payload dword */
244269 pci_read_config_dword (pdev , offset + PCI_DOE_READ , & val );
245- task -> response_pl [i ] = cpu_to_le32 (val );
270+ cpu_to_le32s (& val );
271+ memcpy (& task -> response_pl [i ], & val , remainder );
246272 /* Prior to the last ack, ensure Data Object Ready */
247- if (i == ( payload_length - 1 ) && !pci_doe_data_obj_ready (doe_mb ))
273+ if (!pci_doe_data_obj_ready (doe_mb ))
248274 return - EIO ;
249275 pci_write_config_dword (pdev , offset + PCI_DOE_READ , 0 );
276+ i ++ ;
250277 }
251278
252279 /* Flush excess length */
@@ -260,7 +287,7 @@ static int pci_doe_recv_resp(struct pci_doe_mb *doe_mb, struct pci_doe_task *tas
260287 if (FIELD_GET (PCI_DOE_STATUS_ERROR , val ))
261288 return - EIO ;
262289
263- return min ( length , task -> response_pl_sz / sizeof ( __le32 )) * sizeof ( __le32 ) ;
290+ return received ;
264291}
265292
266293static void signal_task_complete (struct pci_doe_task * task , int rv )
@@ -561,14 +588,6 @@ static int pci_doe_submit_task(struct pci_doe_mb *doe_mb,
561588 if (!pci_doe_supports_prot (doe_mb , task -> prot .vid , task -> prot .type ))
562589 return - EINVAL ;
563590
564- /*
565- * DOE requests must be a whole number of DW and the response needs to
566- * be big enough for at least 1 DW
567- */
568- if (task -> request_pl_sz % sizeof (__le32 ) ||
569- task -> response_pl_sz < sizeof (__le32 ))
570- return - EINVAL ;
571-
572591 if (test_bit (PCI_DOE_FLAG_DEAD , & doe_mb -> flags ))
573592 return - EIO ;
574593
@@ -596,6 +615,11 @@ static int pci_doe_submit_task(struct pci_doe_mb *doe_mb,
596615 * without byte-swapping. If payloads contain little-endian register values,
597616 * the caller is responsible for conversion with cpu_to_le32() / le32_to_cpu().
598617 *
618+ * For convenience, arbitrary payload sizes are allowed even though PCIe r6.0
619+ * sec 6.30.1 specifies the Data Object Header 2 "Length" in dwords. The last
620+ * (partial) dword is copied with byte granularity and padded with zeroes if
621+ * necessary. Callers are thus relieved of using dword-sized bounce buffers.
622+ *
599623 * RETURNS: Length of received response or negative errno.
600624 * Received data in excess of @response_sz is discarded.
601625 * The length may be smaller than @response_sz and the caller
0 commit comments