Skip to content

Commit ebe4560

Browse files
Oscar CarterGustavoARSilva
authored andcommitted
firewire: Remove function callback casts
In 1394 OHCI specification, Isochronous Receive DMA context has several modes. One of mode is 'BufferFill' and Linux FireWire stack uses it to receive isochronous packets for multiple isochronous channel as FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL. The mode is not used by in-kernel driver, while it's available for userspace. The character device driver in firewire-core includes cast of function callback for the mode since the type of callback function is different from the other modes. The case is inconvenient to effort of Control Flow Integrity builds due to -Wcast-function-type warning. This commit removes the cast. A static helper function is newly added to initialize isochronous context for the mode. The helper function arranges isochronous context to assign specific callback function after call of existent kernel API. It's noticeable that the number of isochronous channel, speed, and the size of header are not required for the mode. The helper function is used for the mode by character device driver instead of direct call of existent kernel API. The same goal can be achieved (in the ioctl_create_iso_context function) without this helper function as follows: - Call the fw_iso_context_create function passing NULL to the callback parameter. - Then setting the context->callback.sc or context->callback.mc variables based on the a->type value. However using the helper function created in this patch makes code more clear and declarative. This way avoid the call to a function with one purpose to achieved another one. Co-developed-by: Takashi Sakamoto <[email protected]> Signed-off-by: Takashi Sakamoto <[email protected]> Co-developed-by: Stefan Richter <[email protected]> Signed-off-by: Stefan Richter <[email protected]> Signed-off-by: Oscar Carter <[email protected]> Reviewed-by: Takashi Sakamoto <[email protected]> Testeb-by: Takashi Sakamoto<[email protected]> Signed-off-by: Gustavo A. R. Silva <[email protected]>
1 parent 71e4bbc commit ebe4560

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

drivers/firewire/core-cdev.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/delay.h>
1111
#include <linux/device.h>
1212
#include <linux/dma-mapping.h>
13+
#include <linux/err.h>
1314
#include <linux/errno.h>
1415
#include <linux/firewire.h>
1516
#include <linux/firewire-cdev.h>
@@ -953,11 +954,25 @@ static enum dma_data_direction iso_dma_direction(struct fw_iso_context *context)
953954
return DMA_FROM_DEVICE;
954955
}
955956

957+
static struct fw_iso_context *fw_iso_mc_context_create(struct fw_card *card,
958+
fw_iso_mc_callback_t callback,
959+
void *callback_data)
960+
{
961+
struct fw_iso_context *ctx;
962+
963+
ctx = fw_iso_context_create(card, FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL,
964+
0, 0, 0, NULL, callback_data);
965+
if (!IS_ERR(ctx))
966+
ctx->callback.mc = callback;
967+
968+
return ctx;
969+
}
970+
956971
static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg)
957972
{
958973
struct fw_cdev_create_iso_context *a = &arg->create_iso_context;
959974
struct fw_iso_context *context;
960-
fw_iso_callback_t cb;
975+
union fw_iso_callback cb;
961976
int ret;
962977

963978
BUILD_BUG_ON(FW_CDEV_ISO_CONTEXT_TRANSMIT != FW_ISO_CONTEXT_TRANSMIT ||
@@ -970,27 +985,32 @@ static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg)
970985
if (a->speed > SCODE_3200 || a->channel > 63)
971986
return -EINVAL;
972987

973-
cb = iso_callback;
988+
cb.sc = iso_callback;
974989
break;
975990

976991
case FW_ISO_CONTEXT_RECEIVE:
977992
if (a->header_size < 4 || (a->header_size & 3) ||
978993
a->channel > 63)
979994
return -EINVAL;
980995

981-
cb = iso_callback;
996+
cb.sc = iso_callback;
982997
break;
983998

984999
case FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL:
985-
cb = (fw_iso_callback_t)iso_mc_callback;
1000+
cb.mc = iso_mc_callback;
9861001
break;
9871002

9881003
default:
9891004
return -EINVAL;
9901005
}
9911006

992-
context = fw_iso_context_create(client->device->card, a->type,
993-
a->channel, a->speed, a->header_size, cb, client);
1007+
if (a->type == FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL)
1008+
context = fw_iso_mc_context_create(client->device->card, cb.mc,
1009+
client);
1010+
else
1011+
context = fw_iso_context_create(client->device->card, a->type,
1012+
a->channel, a->speed,
1013+
a->header_size, cb.sc, client);
9941014
if (IS_ERR(context))
9951015
return PTR_ERR(context);
9961016
if (client->version < FW_CDEV_VERSION_AUTO_FLUSH_ISO_OVERFLOW)

include/linux/firewire.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -436,17 +436,20 @@ typedef void (*fw_iso_callback_t)(struct fw_iso_context *context,
436436
void *header, void *data);
437437
typedef void (*fw_iso_mc_callback_t)(struct fw_iso_context *context,
438438
dma_addr_t completed, void *data);
439+
440+
union fw_iso_callback {
441+
fw_iso_callback_t sc;
442+
fw_iso_mc_callback_t mc;
443+
};
444+
439445
struct fw_iso_context {
440446
struct fw_card *card;
441447
int type;
442448
int channel;
443449
int speed;
444450
bool drop_overflow_headers;
445451
size_t header_size;
446-
union {
447-
fw_iso_callback_t sc;
448-
fw_iso_mc_callback_t mc;
449-
} callback;
452+
union fw_iso_callback callback;
450453
void *callback_data;
451454
};
452455

0 commit comments

Comments
 (0)