]> Pileus Git - ~andy/linux/blobdiff - drivers/staging/tidspbridge/dynload/cload.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[~andy/linux] / drivers / staging / tidspbridge / dynload / cload.c
index fe1ef0addb09e4da2cf73f7fe36fac818b2bb436..9d54744805b88a6ea9a3dba376685800996c34dd 100644 (file)
@@ -14,6 +14,8 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
+#include <linux/slab.h>
+
 #include "header.h"
 
 #include "module_list.h"
@@ -706,6 +708,7 @@ static void dload_symbols(struct dload_state *dlthis)
        struct local_symbol *sp;
        struct dynload_symbol *symp;
        struct dynload_symbol *newsym;
+       struct doff_syment_t *my_sym_buf;
 
        sym_count = dlthis->dfile_hdr.df_no_syms;
        if (sym_count == 0)
@@ -739,13 +742,18 @@ static void dload_symbols(struct dload_state *dlthis)
         become defined from the global symbol table */
        checks = dlthis->verify.dv_sym_tab_checksum;
        symbols_left = sym_count;
+
+       my_sym_buf = kzalloc(sizeof(*my_sym_buf) * MY_SYM_BUF_SIZ, GFP_KERNEL);
+       if (!my_sym_buf)
+               return;
+
        do {                    /* read all symbols */
                char *sname;
                u32 val;
                s32 delta;
                struct doff_syment_t *input_sym;
                unsigned syms_in_buf;
-               struct doff_syment_t my_sym_buf[MY_SYM_BUF_SIZ];
+
                input_sym = my_sym_buf;
                syms_in_buf = symbols_left > MY_SYM_BUF_SIZ ?
                    MY_SYM_BUF_SIZ : symbols_left;
@@ -753,7 +761,7 @@ static void dload_symbols(struct dload_state *dlthis)
                if (dlthis->strm->read_buffer(dlthis->strm, input_sym, siz) !=
                    siz) {
                        DL_ERROR(readstrm, sym_errid);
-                       return;
+                       goto free_sym_buf;
                }
                if (dlthis->reorder_map)
                        dload_reorder(input_sym, siz, dlthis->reorder_map);
@@ -856,7 +864,7 @@ static void dload_symbols(struct dload_state *dlthis)
                                        DL_ERROR("Absolute symbol %s is "
                                                 "defined multiple times with "
                                                 "different values", sname);
-                                       return;
+                                       goto free_sym_buf;
                                }
                        }
 loop_itr:
@@ -887,6 +895,9 @@ loop_cont:
        if (~checks)
                dload_error(dlthis, "Checksum of symbols failed");
 
+free_sym_buf:
+       kfree(my_sym_buf);
+       return;
 }                              /* dload_symbols */
 
 /*****************************************************************************
@@ -1116,6 +1127,11 @@ static int relocate_packet(struct dload_state *dlthis,
 /* VERY dangerous */
 static const char imagepak[] = { "image packet" };
 
+struct img_buffer {
+       struct image_packet_t ipacket;
+       u8 bufr[BYTE_TO_HOST(IMAGE_PACKET_SIZE)];
+};
+
 /*************************************************************************
  * Procedure dload_data
  *
@@ -1131,16 +1147,16 @@ static void dload_data(struct dload_state *dlthis)
        u16 curr_sect;
        struct doff_scnhdr_t *sptr = dlthis->sect_hdrs;
        struct ldr_section_info *lptr = dlthis->ldr_sections;
+       struct img_buffer *ibuf;
        u8 *dest;
 
-       struct {
-               struct image_packet_t ipacket;
-               u8 bufr[BYTE_TO_HOST(IMAGE_PACKET_SIZE)];
-       } ibuf;
-
        /* Indicates whether CINIT processing has occurred */
        bool cinit_processed = false;
 
+       ibuf = kzalloc(sizeof(*ibuf), GFP_KERNEL);
+       if (!ibuf)
+               return;
+
        /* Loop through the sections and load them one at a time.
         */
        for (curr_sect = 0; curr_sect < dlthis->dfile_hdr.df_no_scns;
@@ -1168,37 +1184,37 @@ static void dload_data(struct dload_state *dlthis)
 
                                /* get the fixed header bits */
                                if (dlthis->strm->read_buffer(dlthis->strm,
-                                                             &ibuf.ipacket,
+                                                             &ibuf->ipacket,
                                                              IPH_SIZE) !=
                                    IPH_SIZE) {
                                        DL_ERROR(readstrm, imagepak);
-                                       return;
+                                       goto free_ibuf;
                                }
                                /* reorder the header if need be */
                                if (dlthis->reorder_map) {
-                                       dload_reorder(&ibuf.ipacket, IPH_SIZE,
+                                       dload_reorder(&ibuf->ipacket, IPH_SIZE,
                                                      dlthis->reorder_map);
                                }
                                /* now read the rest of the packet */
                                ipsize =
                                    BYTE_TO_HOST(DOFF_ALIGN
-                                                (ibuf.ipacket.packet_size));
+                                                (ibuf->ipacket.packet_size));
                                if (ipsize > BYTE_TO_HOST(IMAGE_PACKET_SIZE)) {
                                        DL_ERROR("Bad image packet size %d",
                                                 ipsize);
-                                       return;
+                                       goto free_ibuf;
                                }
-                               dest = ibuf.bufr;
+                               dest = ibuf->bufr;
                                /* End of determination */
 
                                if (dlthis->strm->read_buffer(dlthis->strm,
-                                                             ibuf.bufr,
+                                                             ibuf->bufr,
                                                              ipsize) !=
                                    ipsize) {
                                        DL_ERROR(readstrm, imagepak);
-                                       return;
+                                       goto free_ibuf;
                                }
-                               ibuf.ipacket.img_data = dest;
+                               ibuf->ipacket.img_data = dest;
 
                                /* reorder the bytes if need be */
 #if !defined(_BIG_ENDIAN) || (TARGET_AU_BITS > 16)
@@ -1225,16 +1241,16 @@ static void dload_data(struct dload_state *dlthis)
 #endif
 #endif
 
-                               checks += dload_checksum(&ibuf.ipacket,
+                               checks += dload_checksum(&ibuf->ipacket,
                                                         IPH_SIZE);
                                /* relocate the image bits as needed */
-                               if (ibuf.ipacket.num_relocs) {
+                               if (ibuf->ipacket.num_relocs) {
                                        dlthis->image_offset = image_offset;
                                        if (!relocate_packet(dlthis,
-                                                            &ibuf.ipacket,
+                                                            &ibuf->ipacket,
                                                             &checks,
                                                             &tramp_generated))
-                                               return; /* serious error */
+                                               goto free_ibuf; /* error */
                                }
                                if (~checks)
                                        DL_ERROR(err_checksum, imagepak);
@@ -1249,20 +1265,20 @@ static void dload_data(struct dload_state *dlthis)
                                        if (dload_check_type(sptr,
                                                DLOAD_CINIT)) {
                                                cload_cinit(dlthis,
-                                                           &ibuf.ipacket);
+                                                           &ibuf->ipacket);
                                                cinit_processed = true;
                                        } else {
                                                /* FIXME */
                                                if (!dlthis->myio->
                                                    writemem(dlthis->
                                                        myio,
-                                                       ibuf.bufr,
+                                                       ibuf->bufr,
                                                        lptr->
                                                        load_addr +
                                                        image_offset,
                                                        lptr,
                                                        BYTE_TO_HOST
-                                                       (ibuf.
+                                                       (ibuf->
                                                        ipacket.
                                                        packet_size))) {
                                                        DL_ERROR
@@ -1276,7 +1292,7 @@ static void dload_data(struct dload_state *dlthis)
                                        }
                                }
                                image_offset +=
-                                   BYTE_TO_TADDR(ibuf.ipacket.packet_size);
+                                   BYTE_TO_TADDR(ibuf->ipacket.packet_size);
                        }       /* process packets */
                        /* if this is a BSS section, we may want to fill it */
                        if (!dload_check_type(sptr, DLOAD_BSS))
@@ -1334,6 +1350,9 @@ loop_cont:
                DL_ERROR("Finalization of auto-trampolines (size = " FMT_UI32
                         ") failed", dlthis->tramp.tramp_sect_next_addr);
        }
+free_ibuf:
+       kfree(ibuf);
+       return;
 }                              /* dload_data */
 
 /*************************************************************************