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

Configure Feed

Select the types of activity you want to include in your feed.

firewire: ohci: refactor isoc single-channel state using a union

In 1394 OHCI driver, some members of struct iso_context are only used for
single-channel isochronous contexts.

This commit groups these members into a union.

Link: https://lore.kernel.org/r/20260117142823.440811-3-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>

+41 -27
+41 -27
drivers/firewire/ohci.c
··· 168 168 struct iso_context { 169 169 struct fw_iso_context base; 170 170 struct context context; 171 - void *header; 172 - size_t header_length; 173 171 unsigned long flushing_completions; 174 172 u32 mc_buffer_bus; 175 173 u16 mc_completed; 176 - u16 last_timestamp; 177 174 u8 sync; 178 175 u8 tags; 176 + union { 177 + struct { 178 + u16 last_timestamp; 179 + size_t header_length; 180 + void *header; 181 + } sc; 182 + }; 179 183 }; 180 184 181 185 #define CONFIG_ROM_SIZE (CSR_CONFIG_ROM_END - CSR_CONFIG_ROM) ··· 2739 2735 2740 2736 static void flush_iso_completions(struct iso_context *ctx, enum fw_iso_context_completions_cause cause) 2741 2737 { 2742 - trace_isoc_inbound_single_completions(&ctx->base, ctx->last_timestamp, cause, ctx->header, 2743 - ctx->header_length); 2744 - trace_isoc_outbound_completions(&ctx->base, ctx->last_timestamp, cause, ctx->header, 2745 - ctx->header_length); 2738 + trace_isoc_inbound_single_completions(&ctx->base, ctx->sc.last_timestamp, cause, 2739 + ctx->sc.header, ctx->sc.header_length); 2740 + trace_isoc_outbound_completions(&ctx->base, ctx->sc.last_timestamp, cause, ctx->sc.header, 2741 + ctx->sc.header_length); 2746 2742 2747 - ctx->base.callback.sc(&ctx->base, ctx->last_timestamp, 2748 - ctx->header_length, ctx->header, 2749 - ctx->base.callback_data); 2750 - ctx->header_length = 0; 2743 + ctx->base.callback.sc(&ctx->base, ctx->sc.last_timestamp, ctx->sc.header_length, 2744 + ctx->sc.header, ctx->base.callback_data); 2745 + ctx->sc.header_length = 0; 2751 2746 } 2752 2747 2753 2748 static void copy_iso_headers(struct iso_context *ctx, const u32 *dma_hdr) 2754 2749 { 2755 2750 u32 *ctx_hdr; 2756 2751 2757 - if (ctx->header_length + ctx->base.header_size > PAGE_SIZE) { 2752 + if (ctx->sc.header_length + ctx->base.header_size > PAGE_SIZE) { 2758 2753 if (ctx->base.drop_overflow_headers) 2759 2754 return; 2760 2755 flush_iso_completions(ctx, FW_ISO_CONTEXT_COMPLETIONS_CAUSE_HEADER_OVERFLOW); 2761 2756 } 2762 2757 2763 - ctx_hdr = ctx->header + ctx->header_length; 2764 - ctx->last_timestamp = (u16)le32_to_cpu((__force __le32)dma_hdr[0]); 2758 + ctx_hdr = ctx->sc.header + ctx->sc.header_length; 2759 + ctx->sc.last_timestamp = (u16)le32_to_cpu((__force __le32)dma_hdr[0]); 2765 2760 2766 2761 /* 2767 2762 * The two iso header quadlets are byteswapped to little ··· 2773 2770 ctx_hdr[1] = swab32(dma_hdr[0]); /* timestamp */ 2774 2771 if (ctx->base.header_size > 8) 2775 2772 memcpy(&ctx_hdr[2], &dma_hdr[2], ctx->base.header_size - 8); 2776 - ctx->header_length += ctx->base.header_size; 2773 + ctx->sc.header_length += ctx->base.header_size; 2777 2774 } 2778 2775 2779 2776 static int handle_ir_packet_per_buffer(struct context *context, ··· 2923 2920 2924 2921 sync_it_packet_for_cpu(context, d); 2925 2922 2926 - if (ctx->header_length + 4 > PAGE_SIZE) { 2923 + if (ctx->sc.header_length + 4 > PAGE_SIZE) { 2927 2924 if (ctx->base.drop_overflow_headers) 2928 2925 return 1; 2929 2926 flush_iso_completions(ctx, FW_ISO_CONTEXT_COMPLETIONS_CAUSE_HEADER_OVERFLOW); 2930 2927 } 2931 2928 2932 - ctx_hdr = ctx->header + ctx->header_length; 2933 - ctx->last_timestamp = le16_to_cpu(last->res_count); 2929 + ctx_hdr = ctx->sc.header + ctx->sc.header_length; 2930 + ctx->sc.last_timestamp = le16_to_cpu(last->res_count); 2934 2931 /* Present this value as big-endian to match the receive code */ 2935 2932 *ctx_hdr = cpu_to_be32((le16_to_cpu(pd->transfer_status) << 16) | 2936 2933 le16_to_cpu(pd->res_count)); 2937 - ctx->header_length += 4; 2934 + ctx->sc.header_length += 4; 2938 2935 2939 2936 if (last->control & cpu_to_le16(DESCRIPTOR_IRQ_ALWAYS)) 2940 2937 flush_iso_completions(ctx, FW_ISO_CONTEXT_COMPLETIONS_CAUSE_INTERRUPT); ··· 3011 3008 } 3012 3009 3013 3010 memset(ctx, 0, sizeof(*ctx)); 3014 - ctx->header_length = 0; 3015 - ctx->header = (void *) __get_free_page(GFP_KERNEL); 3016 - if (ctx->header == NULL) { 3017 - ret = -ENOMEM; 3018 - goto out; 3011 + 3012 + if (type != FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL) { 3013 + ctx->sc.header_length = 0; 3014 + ctx->sc.header = (void *) __get_free_page(GFP_KERNEL); 3015 + if (!ctx->sc.header) { 3016 + ret = -ENOMEM; 3017 + goto out; 3018 + } 3019 3019 } 3020 + 3020 3021 ret = context_init(&ctx->context, ohci, regs, callback); 3021 3022 if (ret < 0) 3022 3023 goto out_with_header; ··· 3034 3027 return &ctx->base; 3035 3028 3036 3029 out_with_header: 3037 - free_page((unsigned long)ctx->header); 3030 + if (type != FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL) { 3031 + free_page((unsigned long)ctx->sc.header); 3032 + ctx->sc.header = NULL; 3033 + } 3038 3034 out: 3039 3035 scoped_guard(spinlock_irq, &ohci->lock) { 3040 3036 switch (type) { ··· 3137 3127 3138 3128 ohci_stop_iso(base); 3139 3129 context_release(&ctx->context); 3140 - free_page((unsigned long)ctx->header); 3130 + 3131 + if (base->type != FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL) { 3132 + free_page((unsigned long)ctx->sc.header); 3133 + ctx->sc.header = NULL; 3134 + } 3141 3135 3142 3136 guard(spinlock_irqsave)(&ohci->lock); 3143 3137 ··· 3489 3475 switch (base->type) { 3490 3476 case FW_ISO_CONTEXT_TRANSMIT: 3491 3477 case FW_ISO_CONTEXT_RECEIVE: 3492 - if (ctx->header_length != 0) 3478 + if (ctx->sc.header_length != 0) 3493 3479 flush_iso_completions(ctx, FW_ISO_CONTEXT_COMPLETIONS_CAUSE_FLUSH); 3494 3480 break; 3495 3481 case FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL: