Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

greybus: gb-beagleplay: Remove use of pad bytes

Make gb-beagleplay greybus spec compliant by moving cport information to
transport layer instead of using `header->pad` bytes.

Greybus HDLC frame now has the following payload:
1. le16 cport
2. gb_operation_msg_hdr msg_header
3. u8 *msg_payload

Fixes: ec558bbfea67 ("greybus: Add BeaglePlay Linux Driver")
Signed-off-by: Ayush Singh <ayushdevel1325@gmail.com>
Link: https://lore.kernel.org/r/20231217121133.74703-2-ayushdevel1325@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Ayush Singh and committed by
Greg Kroah-Hartman
08b34855 6aa1fc5a

+43 -15
+43 -15
drivers/greybus/gb-beagleplay.c
··· 85 85 void *buf; 86 86 }; 87 87 88 + /** 89 + * struct hdlc_greybus_frame - Structure to represent greybus HDLC frame payload 90 + * 91 + * @cport: cport id 92 + * @hdr: greybus operation header 93 + * @payload: greybus message payload 94 + * 95 + * The HDLC payload sent over UART for greybus address has cport preappended to greybus message 96 + */ 97 + struct hdlc_greybus_frame { 98 + __le16 cport; 99 + struct gb_operation_msg_hdr hdr; 100 + u8 payload[]; 101 + } __packed; 102 + 88 103 static void hdlc_rx_greybus_frame(struct gb_beagleplay *bg, u8 *buf, u16 len) 89 104 { 90 - u16 cport_id; 91 - struct gb_operation_msg_hdr *hdr = (struct gb_operation_msg_hdr *)buf; 92 - 93 - memcpy(&cport_id, hdr->pad, sizeof(cport_id)); 105 + struct hdlc_greybus_frame *gb_frame = (struct hdlc_greybus_frame *)buf; 106 + u16 cport_id = le16_to_cpu(gb_frame->cport); 107 + u16 gb_msg_len = le16_to_cpu(gb_frame->hdr.size); 94 108 95 109 dev_dbg(&bg->sd->dev, "Greybus Operation %u type %X cport %u status %u received", 96 - hdr->operation_id, hdr->type, cport_id, hdr->result); 110 + gb_frame->hdr.operation_id, gb_frame->hdr.type, cport_id, gb_frame->hdr.result); 97 111 98 - greybus_data_rcvd(bg->gb_hd, cport_id, buf, len); 112 + greybus_data_rcvd(bg->gb_hd, cport_id, (u8 *)&gb_frame->hdr, gb_msg_len); 99 113 } 100 114 101 115 static void hdlc_rx_dbg_frame(const struct gb_beagleplay *bg, const char *buf, u16 len) ··· 350 336 .write_wakeup = gb_tty_wakeup, 351 337 }; 352 338 339 + /** 340 + * gb_message_send() - Send greybus message using HDLC over UART 341 + * 342 + * @hd: pointer to greybus host device 343 + * @cport: AP cport where message originates 344 + * @msg: greybus message to send 345 + * @mask: gfp mask 346 + * 347 + * Greybus HDLC frame has the following payload: 348 + * 1. le16 cport 349 + * 2. gb_operation_msg_hdr msg_header 350 + * 3. u8 *msg_payload 351 + */ 353 352 static int gb_message_send(struct gb_host_device *hd, u16 cport, struct gb_message *msg, gfp_t mask) 354 353 { 355 354 struct gb_beagleplay *bg = dev_get_drvdata(&hd->dev); 356 - struct hdlc_payload payloads[2]; 355 + struct hdlc_payload payloads[3]; 356 + __le16 cport_id = cpu_to_le16(cport); 357 357 358 358 dev_dbg(&hd->dev, "Sending greybus message with Operation %u, Type: %X on Cport %u", 359 359 msg->header->operation_id, msg->header->type, cport); 360 360 361 - if (msg->header->size > RX_HDLC_PAYLOAD) 361 + if (le16_to_cpu(msg->header->size) > RX_HDLC_PAYLOAD) 362 362 return dev_err_probe(&hd->dev, -E2BIG, "Greybus message too big"); 363 363 364 - memcpy(msg->header->pad, &cport, sizeof(cport)); 364 + payloads[0].buf = &cport_id; 365 + payloads[0].len = sizeof(cport_id); 366 + payloads[1].buf = msg->header; 367 + payloads[1].len = sizeof(*msg->header); 368 + payloads[2].buf = msg->payload; 369 + payloads[2].len = msg->payload_size; 365 370 366 - payloads[0].buf = msg->header; 367 - payloads[0].len = sizeof(*msg->header); 368 - payloads[1].buf = msg->payload; 369 - payloads[1].len = msg->payload_size; 370 - 371 - hdlc_tx_frames(bg, ADDRESS_GREYBUS, 0x03, payloads, 2); 371 + hdlc_tx_frames(bg, ADDRESS_GREYBUS, 0x03, payloads, 3); 372 372 greybus_message_sent(bg->gb_hd, msg, 0); 373 373 374 374 return 0;