diff options
Diffstat (limited to 'drivers/staging/wlan-ng/prism2fw.c')
| -rw-r--r-- | drivers/staging/wlan-ng/prism2fw.c | 452 |
1 files changed, 235 insertions, 217 deletions
diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index aaa70ed5771..f7870355c69 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -48,11 +48,13 @@ /*================================================================*/ /* System Includes */ #include <linux/ihex.h> +#include <linux/slab.h> /*================================================================*/ /* Local Constants */ #define PRISM2_USB_FWFILE "prism2_ru.fw" +MODULE_FIRMWARE(PRISM2_USB_FWFILE); #define S3DATA_MAX 5000 #define S3PLUG_MAX 200 @@ -71,26 +73,26 @@ /*================================================================*/ /* Local Types */ -typedef struct s3datarec { +struct s3datarec { u32 len; u32 addr; u8 checksum; u8 *data; -} s3datarec_t; +}; -typedef struct s3plugrec { +struct s3plugrec { u32 itemcode; u32 addr; u32 len; -} s3plugrec_t; +}; -typedef struct s3crcrec { +struct s3crcrec { u32 addr; u32 len; unsigned int dowrite; -} s3crcrec_t; +}; -typedef struct s3inforec { +struct s3inforec { u16 len; u16 type; union { @@ -99,20 +101,20 @@ typedef struct s3inforec { u16 buildseq; hfa384x_compident_t platform; } info; -} s3inforec_t; +}; -typedef struct pda { +struct pda { u8 buf[HFA384x_PDA_LEN_MAX]; hfa384x_pdrec_t *rec[HFA384x_PDA_RECS_MAX]; unsigned int nrec; -} pda_t; +}; -typedef struct imgchunk { - u32 addr; /* start address */ - u32 len; /* in bytes */ - u16 crc; /* CRC value (if it falls at a chunk boundary) */ +struct imgchunk { + u32 addr; /* start address */ + u32 len; /* in bytes */ + u16 crc; /* CRC value (if it falls at a chunk boundary) */ u8 *data; -} imgchunk_t; +}; /*================================================================*/ /* Local Static Definitions */ @@ -121,27 +123,27 @@ typedef struct imgchunk { /* s-record image processing */ /* Data records */ -unsigned int ns3data; -s3datarec_t s3data[S3DATA_MAX]; +static unsigned int ns3data; +static struct s3datarec s3data[S3DATA_MAX]; /* Plug records */ -unsigned int ns3plug; -s3plugrec_t s3plug[S3PLUG_MAX]; +static unsigned int ns3plug; +static struct s3plugrec s3plug[S3PLUG_MAX]; /* CRC records */ -unsigned int ns3crc; -s3crcrec_t s3crc[S3CRC_MAX]; +static unsigned int ns3crc; +static struct s3crcrec s3crc[S3CRC_MAX]; /* Info records */ -unsigned int ns3info; -s3inforec_t s3info[S3INFO_MAX]; +static unsigned int ns3info; +static struct s3inforec s3info[S3INFO_MAX]; /* S7 record (there _better_ be only one) */ -u32 startaddr; +static u32 startaddr; /* Load image chunks */ -unsigned int nfchunks; -imgchunk_t fchunk[CHUNKS_MAX]; +static unsigned int nfchunks; +static struct imgchunk fchunk[CHUNKS_MAX]; /* Note that for the following pdrec_t arrays, the len and code */ /* fields are stored in HOST byte order. The mkpdrlist() function */ @@ -149,30 +151,39 @@ imgchunk_t fchunk[CHUNKS_MAX]; /*----------------------------------------------------------------*/ /* PDA, built from [card|newfile]+[addfile1+addfile2...] */ -pda_t pda; -hfa384x_compident_t nicid; -hfa384x_caplevel_t rfid; -hfa384x_caplevel_t macid; -hfa384x_caplevel_t priid; +static struct pda pda; +static hfa384x_compident_t nicid; +static hfa384x_caplevel_t rfid; +static hfa384x_caplevel_t macid; +static hfa384x_caplevel_t priid; /*================================================================*/ /* Local Function Declarations */ -int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev); -int read_fwfile(const struct ihex_binrec *rfptr); -int mkimage(imgchunk_t *clist, unsigned int *ccnt); -int read_cardpda(pda_t *pda, wlandevice_t *wlandev); -int mkpdrlist(pda_t *pda); -int plugimage(imgchunk_t *fchunk, unsigned int nfchunks, - s3plugrec_t *s3plug, unsigned int ns3plug, pda_t * pda); -int crcimage(imgchunk_t *fchunk, unsigned int nfchunks, - s3crcrec_t *s3crc, unsigned int ns3crc); -int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk, +static int prism2_fwapply(const struct ihex_binrec *rfptr, +wlandevice_t *wlandev); + +static int read_fwfile(const struct ihex_binrec *rfptr); + +static int mkimage(struct imgchunk *clist, unsigned int *ccnt); + +static int read_cardpda(struct pda *pda, wlandevice_t *wlandev); + +static int mkpdrlist(struct pda *pda); + +static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks, + struct s3plugrec *s3plug, unsigned int ns3plug, struct pda *pda); + +static int crcimage(struct imgchunk *fchunk, unsigned int nfchunks, + struct s3crcrec *s3crc, unsigned int ns3crc); + +static int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, unsigned int nfchunks); -void free_chunks(imgchunk_t *fchunk, unsigned int *nfchunks); -void free_srecs(void); +static void free_chunks(struct imgchunk *fchunk, unsigned int *nfchunks); + +static void free_srecs(void); -int validate_identity(void); +static int validate_identity(void); /*================================================================*/ /* Function Definitions */ @@ -190,22 +201,24 @@ int validate_identity(void); * 0 - success * ~0 - failure ----------------------------------------------------------------*/ -int prism2_fwtry(struct usb_device *udev, wlandevice_t *wlandev) +static int prism2_fwtry(struct usb_device *udev, wlandevice_t *wlandev) { const struct firmware *fw_entry = NULL; - printk(KERN_INFO "prism2_usb: Checking for firmware %s\n", + netdev_info(wlandev->netdev, "prism2_usb: Checking for firmware %s\n", PRISM2_USB_FWFILE); - if (request_ihex_firmware(&fw_entry, PRISM2_USB_FWFILE, &udev->dev) != 0) { - printk(KERN_INFO + if (request_ihex_firmware(&fw_entry, + PRISM2_USB_FWFILE, &udev->dev) != 0) { + netdev_info(wlandev->netdev, "prism2_usb: Firmware not available, but not essential\n"); - printk(KERN_INFO + netdev_info(wlandev->netdev, "prism2_usb: can continue to use card anyway.\n"); return 1; } - printk(KERN_INFO "prism2_usb: %s will be processed, size %d\n", - PRISM2_USB_FWFILE, fw_entry->size); + netdev_info(wlandev->netdev, + "prism2_usb: %s will be processed, size %zu\n", + PRISM2_USB_FWFILE, fw_entry->size); prism2_fwapply((const struct ihex_binrec *)fw_entry->data, wlandev); release_firmware(fw_entry); @@ -225,10 +238,10 @@ int prism2_fwtry(struct usb_device *udev, wlandevice_t *wlandev) * 0 - success * ~0 - failure ----------------------------------------------------------------*/ -int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev) +static int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev) { signed int result = 0; - p80211msg_dot11req_mibget_t getmsg; + struct p80211msg_dot11req_mibget getmsg; p80211itemd_t *item; u32 *data; @@ -253,7 +266,7 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev) /* clear the pda and add an initial END record */ memset(&pda, 0, sizeof(pda)); pda.rec[0] = (hfa384x_pdrec_t *) pda.buf; - pda.rec[0]->len = cpu_to_le16(2); /* len in words *//* len in words */ + pda.rec[0]->len = cpu_to_le16(2); /* len in words */ pda.rec[0]->code = cpu_to_le16(HFA384x_PDR_END_OF_PDA); pda.nrec = 1; @@ -263,8 +276,8 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev) /* Build the PDA we're going to use. */ if (read_cardpda(&pda, wlandev)) { - printk(KERN_ERR "load_cardpda failed, exiting.\n"); - return (1); + netdev_err(wlandev->netdev, "load_cardpda failed, exiting.\n"); + return 1; } /* read the card's PRI-SUP */ @@ -286,9 +299,8 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev) /* DIDmsg_dot11req_mibget */ prism2mgmt_mibset_mibget(wlandev, &getmsg); - if (getmsg.resultcode.data != P80211ENUM_resultcode_success) { - printk(KERN_ERR "Couldn't fetch PRI-SUP info\n"); - } + if (getmsg.resultcode.data != P80211ENUM_resultcode_success) + netdev_err(wlandev->netdev, "Couldn't fetch PRI-SUP info\n"); /* Already in host order */ priid.role = *data++; @@ -300,20 +312,22 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev) /* Read the S3 file */ result = read_fwfile(rfptr); if (result) { - printk(KERN_ERR "Failed to read the data exiting.\n"); - return (1); + netdev_err(wlandev->netdev, + "Failed to read the data exiting.\n"); + return 1; } result = validate_identity(); if (result) { - printk(KERN_ERR "Incompatible firmware image.\n"); - return (1); + netdev_err(wlandev->netdev, "Incompatible firmware image.\n"); + return 1; } if (startaddr == 0x00000000) { - printk(KERN_ERR "Can't RAM download a Flash image!\n"); - return (1); + netdev_err(wlandev->netdev, + "Can't RAM download a Flash image!\n"); + return 1; } /* Make the image chunks */ @@ -322,28 +336,28 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev) /* Do any plugging */ result = plugimage(fchunk, nfchunks, s3plug, ns3plug, &pda); if (result) { - printk(KERN_ERR "Failed to plug data.\n"); - return (1); + netdev_err(wlandev->netdev, "Failed to plug data.\n"); + return 1; } /* Insert any CRCs */ if (crcimage(fchunk, nfchunks, s3crc, ns3crc)) { - printk(KERN_ERR "Failed to insert all CRCs\n"); - return (1); + netdev_err(wlandev->netdev, "Failed to insert all CRCs\n"); + return 1; } /* Write the image */ result = writeimage(wlandev, fchunk, nfchunks); if (result) { - printk(KERN_ERR "Failed to ramwrite image data.\n"); - return (1); + netdev_err(wlandev->netdev, "Failed to ramwrite image data.\n"); + return 1; } /* clear any allocated memory */ free_chunks(fchunk, &nfchunks); free_srecs(); - printk(KERN_INFO "prism2_usb: firmware loading finished.\n"); + netdev_info(wlandev->netdev, "prism2_usb: firmware loading finished.\n"); return result; } @@ -365,8 +379,8 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev) * 0 success * ~0 failure ----------------------------------------------------------------*/ -int crcimage(imgchunk_t *fchunk, unsigned int nfchunks, s3crcrec_t *s3crc, - unsigned int ns3crc) +static int crcimage(struct imgchunk *fchunk, unsigned int nfchunks, + struct s3crcrec *s3crc, unsigned int ns3crc) { int result = 0; int i; @@ -387,21 +401,19 @@ int crcimage(imgchunk_t *fchunk, unsigned int nfchunks, s3crcrec_t *s3crc, for (c = 0; c < nfchunks; c++) { cstart = fchunk[c].addr; cend = fchunk[c].addr + fchunk[c].len; - /* the line below does an address & len match search */ - /* unfortunately, I've found that the len fields of */ - /* some crc records don't match with the length of */ - /* the actual data, so we're not checking right */ - /* now */ - /* if ( crcstart-2 >= cstart && crcend <= cend ) break; */ + /* the line below does an address & len match search */ + /* unfortunately, I've found that the len fields of */ + /* some crc records don't match with the length of */ + /* the actual data, so we're not checking right now */ + /* if (crcstart-2 >= cstart && crcend <= cend) break; */ /* note the -2 below, it's to make sure the chunk has */ - /* space for the CRC value */ + /* space for the CRC value */ if (crcstart - 2 >= cstart && crcstart < cend) break; } if (c >= nfchunks) { - printk(KERN_ERR - "Failed to find chunk for " + pr_err("Failed to find chunk for " "crcrec[%d], addr=0x%06x len=%d , " "aborting crc.\n", i, s3crc[i].addr, s3crc[i].len); @@ -430,14 +442,12 @@ int crcimage(imgchunk_t *fchunk, unsigned int nfchunks, s3crcrec_t *s3crc, * Returns: * nothing ----------------------------------------------------------------*/ -void free_chunks(imgchunk_t *fchunk, unsigned int *nfchunks) +static void free_chunks(struct imgchunk *fchunk, unsigned int *nfchunks) { int i; - for (i = 0; i < *nfchunks; i++) { - if (fchunk[i].data != NULL) { - kfree(fchunk[i].data); - } - } + for (i = 0; i < *nfchunks; i++) + kfree(fchunk[i].data); + *nfchunks = 0; memset(fchunk, 0, sizeof(*fchunk)); @@ -454,7 +464,7 @@ void free_chunks(imgchunk_t *fchunk, unsigned int *nfchunks) * Returns: * nothing ----------------------------------------------------------------*/ -void free_srecs(void) +static void free_srecs(void) { ns3data = 0; memset(s3data, 0, sizeof(s3data)); @@ -481,7 +491,7 @@ void free_srecs(void) * 0 - success * ~0 - failure (probably an errno) ----------------------------------------------------------------*/ -int mkimage(imgchunk_t *clist, unsigned int *ccnt) +static int mkimage(struct imgchunk *clist, unsigned int *ccnt) { int result = 0; int i; @@ -527,13 +537,11 @@ int mkimage(imgchunk_t *clist, unsigned int *ccnt) /* Allocate buffer space for chunks */ for (i = 0; i < *ccnt; i++) { - clist[i].data = kmalloc(clist[i].len, GFP_KERNEL); + clist[i].data = kzalloc(clist[i].len, GFP_KERNEL); if (clist[i].data == NULL) { - printk(KERN_ERR - "failed to allocate image space, exitting.\n"); - return (1); + pr_err("failed to allocate image space, exitting.\n"); + return 1; } - memset(clist[i].data, 0, clist[i].len); pr_debug("chunk[%d]: addr=0x%06x len=%d\n", i, clist[i].addr, clist[i].len); } @@ -545,15 +553,13 @@ int mkimage(imgchunk_t *clist, unsigned int *ccnt) for (j = 0; j < *ccnt; j++) { cstart = clist[j].addr; cend = cstart + clist[j].len - 1; - if (s3start >= cstart && s3end <= cend) { + if (s3start >= cstart && s3end <= cend) break; - } } if (((unsigned int)j) >= (*ccnt)) { - printk(KERN_ERR - "s3rec(a=0x%06x,l=%d), no chunk match, exiting.\n", + pr_err("s3rec(a=0x%06x,l=%d), no chunk match, exiting.\n", s3start, s3data[i].len); - return (1); + return 1; } coffset = s3start - cstart; memcpy(clist[j].data + coffset, s3data[i].data, s3data[i].len); @@ -576,7 +582,7 @@ int mkimage(imgchunk_t *clist, unsigned int *ccnt) * 0 - success * ~0 - failure (probably an errno) ----------------------------------------------------------------*/ -int mkpdrlist(pda_t *pda) +static int mkpdrlist(struct pda *pda) { int result = 0; u16 *pda16 = (u16 *) pda->buf; @@ -586,9 +592,10 @@ int mkpdrlist(pda_t *pda) curroff = 0; while (curroff < (HFA384x_PDA_LEN_MAX / 2) && le16_to_cpu(pda16[curroff + 1]) != HFA384x_PDR_END_OF_PDA) { - pda->rec[pda->nrec] = (hfa384x_pdrec_t *) & (pda16[curroff]); + pda->rec[pda->nrec] = (hfa384x_pdrec_t *) &(pda16[curroff]); - if (le16_to_cpu(pda->rec[pda->nrec]->code) == HFA384x_PDR_NICID) { + if (le16_to_cpu(pda->rec[pda->nrec]->code) == + HFA384x_PDR_NICID) { memcpy(&nicid, &pda->rec[pda->nrec]->data.nicid, sizeof(nicid)); nicid.id = le16_to_cpu(nicid.id); @@ -620,13 +627,12 @@ int mkpdrlist(pda_t *pda) } if (curroff >= (HFA384x_PDA_LEN_MAX / 2)) { - printk(KERN_ERR - "no end record found or invalid lengths in " + pr_err("no end record found or invalid lengths in " "PDR data, exiting. %x %d\n", curroff, pda->nrec); - return (1); + return 1; } if (le16_to_cpu(pda16[curroff + 1]) == HFA384x_PDR_END_OF_PDA) { - pda->rec[pda->nrec] = (hfa384x_pdrec_t *) & (pda16[curroff]); + pda->rec[pda->nrec] = (hfa384x_pdrec_t *) &(pda16[curroff]); (pda->nrec)++; } return result; @@ -649,8 +655,8 @@ int mkpdrlist(pda_t *pda) * 0 success * ~0 failure ----------------------------------------------------------------*/ -int plugimage(imgchunk_t *fchunk, unsigned int nfchunks, - s3plugrec_t *s3plug, unsigned int ns3plug, pda_t * pda) +static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks, + struct s3plugrec *s3plug, unsigned int ns3plug, struct pda *pda) { int result = 0; int i; /* plug index */ @@ -668,7 +674,7 @@ int plugimage(imgchunk_t *fchunk, unsigned int nfchunks, pstart = s3plug[i].addr; pend = s3plug[i].addr + s3plug[i].len; /* find the matching PDR (or filename) */ - if (s3plug[i].itemcode != 0xffffffffUL) { /* not filename */ + if (s3plug[i].itemcode != 0xffffffffUL) { /* not filename */ for (j = 0; j < pda->nrec; j++) { if (s3plug[i].itemcode == le16_to_cpu(pda->rec[j]->code)) @@ -677,9 +683,8 @@ int plugimage(imgchunk_t *fchunk, unsigned int nfchunks, } else { j = -1; } - if (j >= pda->nrec && j != -1) { /* if no matching PDR, fail */ - printk(KERN_WARNING - "warning: Failed to find PDR for " + if (j >= pda->nrec && j != -1) { /* if no matching PDR, fail */ + pr_warn("warning: Failed to find PDR for " "plugrec 0x%04x.\n", s3plug[i].itemcode); continue; /* and move on to the next PDR */ #if 0 @@ -697,8 +702,7 @@ int plugimage(imgchunk_t *fchunk, unsigned int nfchunks, /* Validate plug len against PDR len */ if (j != -1 && s3plug[i].len < le16_to_cpu(pda->rec[j]->len)) { - printk(KERN_ERR - "error: Plug vs. PDR len mismatch for " + pr_err("error: Plug vs. PDR len mismatch for " "plugrec 0x%04x, abort plugging.\n", s3plug[i].itemcode); result = 1; @@ -713,8 +717,7 @@ int plugimage(imgchunk_t *fchunk, unsigned int nfchunks, break; } if (c >= nfchunks) { - printk(KERN_ERR - "error: Failed to find image chunk for " + pr_err("error: Failed to find image chunk for " "plugrec 0x%04x.\n", s3plug[i].itemcode); result = 1; continue; @@ -757,10 +760,10 @@ int plugimage(imgchunk_t *fchunk, unsigned int nfchunks, * 0 - success * ~0 - failure (probably an errno) ----------------------------------------------------------------*/ -int read_cardpda(pda_t *pda, wlandevice_t *wlandev) +static int read_cardpda(struct pda *pda, wlandevice_t *wlandev) { int result = 0; - p80211msg_p2req_readpda_t msg; + struct p80211msg_p2req_readpda msg; /* set up the msg */ msg.msgcode = DIDmsg_p2req_readpda; @@ -799,7 +802,7 @@ int read_cardpda(pda_t *pda, wlandevice_t *wlandev) * * Note also that the start address record, originally an S7 record in * the srec file, is expected in the fw file to be like a data record but -* with a certain address to make it identiable. +* with a certain address to make it identifiable. * * Here's the SREC format that the fw should have come from: * S[37]nnaaaaaaaaddd...dddcc @@ -832,7 +835,7 @@ int read_cardpda(pda_t *pda, wlandevice_t *wlandev) * ssssttttdd..dd * s - Size in words (little endian) * t - Info type (little endian), see #defines and -* s3inforec_t for details about types. +* struct s3inforec for details about types. * d - (s - 1) little endian words giving the contents of * the given info type. * @@ -847,7 +850,7 @@ int read_cardpda(pda_t *pda, wlandevice_t *wlandev) * 0 - success * ~0 - failure (probably an errno) ----------------------------------------------------------------*/ -int read_fwfile(const struct ihex_binrec *record) +static int read_fwfile(const struct ihex_binrec *record) { int i; int rcnt = 0; @@ -869,7 +872,7 @@ int read_fwfile(const struct ihex_binrec *record) ptr16 = (u16 *) record->data; /* parse what was an S3 srec and put it in the right array */ - switch(addr) { + switch (addr) { case S3ADDR_START: startaddr = *ptr32; pr_debug(" S7 start addr, record=%d " @@ -890,8 +893,8 @@ int read_fwfile(const struct ihex_binrec *record) s3plug[ns3plug].len); ns3plug++; - if ( ns3plug == S3PLUG_MAX ) { - printk(KERN_ERR "S3 plugrec limit reached - aborting\n"); + if (ns3plug == S3PLUG_MAX) { + pr_err("S3 plugrec limit reached - aborting\n"); return 1; } break; @@ -907,8 +910,8 @@ int read_fwfile(const struct ihex_binrec *record) s3crc[ns3crc].len, s3crc[ns3crc].dowrite); ns3crc++; - if ( ns3crc == S3CRC_MAX ) { - printk(KERN_ERR "S3 crcrec limit reached - aborting\n"); + if (ns3crc == S3CRC_MAX) { + pr_err("S3 crcrec limit reached - aborting\n"); return 1; } break; @@ -921,12 +924,12 @@ int read_fwfile(const struct ihex_binrec *record) rcnt, s3info[ns3info].len, s3info[ns3info].type); - if ( ((s3info[ns3info].len - 1) * sizeof(u16)) > sizeof(s3info[ns3info].info) ) { - printk(KERN_ERR " S3 inforec length too long - aborting\n"); + if (((s3info[ns3info].len - 1) * sizeof(u16)) > sizeof(s3info[ns3info].info)) { + pr_err("S3 inforec length too long - aborting\n"); return 1; } - tmpinfo = (u16*)&(s3info[ns3info].info.version); + tmpinfo = (u16 *)&(s3info[ns3info].info.version); pr_debug(" info="); for (i = 0; i < s3info[ns3info].len - 1; i++) { tmpinfo[i] = *(ptr16 + 2 + i); @@ -935,8 +938,8 @@ int read_fwfile(const struct ihex_binrec *record) pr_debug("\n"); ns3info++; - if ( ns3info == S3INFO_MAX ) { - printk(KERN_ERR "S3 inforec limit reached - aborting\n"); + if (ns3info == S3INFO_MAX) { + pr_err("S3 inforec limit reached - aborting\n"); return 1; } break; @@ -945,8 +948,8 @@ int read_fwfile(const struct ihex_binrec *record) s3data[ns3data].len = len; s3data[ns3data].data = (uint8_t *) record->data; ns3data++; - if ( ns3data == S3DATA_MAX ) { - printk(KERN_ERR "S3 datarec limit reached - aborting\n"); + if (ns3data == S3DATA_MAX) { + pr_err("S3 datarec limit reached - aborting\n"); return 1; } break; @@ -971,13 +974,12 @@ int read_fwfile(const struct ihex_binrec *record) * 0 success * ~0 failure ----------------------------------------------------------------*/ -int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk, +static int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, unsigned int nfchunks) { int result = 0; - p80211msg_p2req_ramdl_state_t rstatemsg; - p80211msg_p2req_ramdl_write_t rwritemsg; - p80211msg_t *msgp; + struct p80211msg_p2req_ramdl_state *rstmsg; + struct p80211msg_p2req_ramdl_write *rwrmsg; u32 resultcode; int i; int j; @@ -986,57 +988,68 @@ int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk, u32 currlen; u32 currdaddr; + rstmsg = kmalloc(sizeof(*rstmsg), GFP_KERNEL); + rwrmsg = kmalloc(sizeof(*rwrmsg), GFP_KERNEL); + if (!rstmsg || !rwrmsg) { + kfree(rstmsg); + kfree(rwrmsg); + netdev_err(wlandev->netdev, + "writeimage: no memory for firmware download, " + "aborting download\n"); + return -ENOMEM; + } + /* Initialize the messages */ - memset(&rstatemsg, 0, sizeof(rstatemsg)); - strcpy(rstatemsg.devname, wlandev->name); - rstatemsg.msgcode = DIDmsg_p2req_ramdl_state; - rstatemsg.msglen = sizeof(rstatemsg); - rstatemsg.enable.did = DIDmsg_p2req_ramdl_state_enable; - rstatemsg.exeaddr.did = DIDmsg_p2req_ramdl_state_exeaddr; - rstatemsg.resultcode.did = DIDmsg_p2req_ramdl_state_resultcode; - rstatemsg.enable.status = P80211ENUM_msgitem_status_data_ok; - rstatemsg.exeaddr.status = P80211ENUM_msgitem_status_data_ok; - rstatemsg.resultcode.status = P80211ENUM_msgitem_status_no_value; - rstatemsg.enable.len = sizeof(u32); - rstatemsg.exeaddr.len = sizeof(u32); - rstatemsg.resultcode.len = sizeof(u32); - - memset(&rwritemsg, 0, sizeof(rwritemsg)); - strcpy(rwritemsg.devname, wlandev->name); - rwritemsg.msgcode = DIDmsg_p2req_ramdl_write; - rwritemsg.msglen = sizeof(rwritemsg); - rwritemsg.addr.did = DIDmsg_p2req_ramdl_write_addr; - rwritemsg.len.did = DIDmsg_p2req_ramdl_write_len; - rwritemsg.data.did = DIDmsg_p2req_ramdl_write_data; - rwritemsg.resultcode.did = DIDmsg_p2req_ramdl_write_resultcode; - rwritemsg.addr.status = P80211ENUM_msgitem_status_data_ok; - rwritemsg.len.status = P80211ENUM_msgitem_status_data_ok; - rwritemsg.data.status = P80211ENUM_msgitem_status_data_ok; - rwritemsg.resultcode.status = P80211ENUM_msgitem_status_no_value; - rwritemsg.addr.len = sizeof(u32); - rwritemsg.len.len = sizeof(u32); - rwritemsg.data.len = WRITESIZE_MAX; - rwritemsg.resultcode.len = sizeof(u32); + memset(rstmsg, 0, sizeof(*rstmsg)); + strcpy(rstmsg->devname, wlandev->name); + rstmsg->msgcode = DIDmsg_p2req_ramdl_state; + rstmsg->msglen = sizeof(*rstmsg); + rstmsg->enable.did = DIDmsg_p2req_ramdl_state_enable; + rstmsg->exeaddr.did = DIDmsg_p2req_ramdl_state_exeaddr; + rstmsg->resultcode.did = DIDmsg_p2req_ramdl_state_resultcode; + rstmsg->enable.status = P80211ENUM_msgitem_status_data_ok; + rstmsg->exeaddr.status = P80211ENUM_msgitem_status_data_ok; + rstmsg->resultcode.status = P80211ENUM_msgitem_status_no_value; + rstmsg->enable.len = sizeof(u32); + rstmsg->exeaddr.len = sizeof(u32); + rstmsg->resultcode.len = sizeof(u32); + + memset(rwrmsg, 0, sizeof(*rwrmsg)); + strcpy(rwrmsg->devname, wlandev->name); + rwrmsg->msgcode = DIDmsg_p2req_ramdl_write; + rwrmsg->msglen = sizeof(*rwrmsg); + rwrmsg->addr.did = DIDmsg_p2req_ramdl_write_addr; + rwrmsg->len.did = DIDmsg_p2req_ramdl_write_len; + rwrmsg->data.did = DIDmsg_p2req_ramdl_write_data; + rwrmsg->resultcode.did = DIDmsg_p2req_ramdl_write_resultcode; + rwrmsg->addr.status = P80211ENUM_msgitem_status_data_ok; + rwrmsg->len.status = P80211ENUM_msgitem_status_data_ok; + rwrmsg->data.status = P80211ENUM_msgitem_status_data_ok; + rwrmsg->resultcode.status = P80211ENUM_msgitem_status_no_value; + rwrmsg->addr.len = sizeof(u32); + rwrmsg->len.len = sizeof(u32); + rwrmsg->data.len = WRITESIZE_MAX; + rwrmsg->resultcode.len = sizeof(u32); /* Send xxx_state(enable) */ pr_debug("Sending dl_state(enable) message.\n"); - rstatemsg.enable.data = P80211ENUM_truth_true; - rstatemsg.exeaddr.data = startaddr; + rstmsg->enable.data = P80211ENUM_truth_true; + rstmsg->exeaddr.data = startaddr; - msgp = (p80211msg_t *) & rstatemsg; - result = prism2mgmt_ramdl_state(wlandev, msgp); + result = prism2mgmt_ramdl_state(wlandev, rstmsg); if (result) { - printk(KERN_ERR - "writeimage state enable failed w/ result=%d, " - "aborting download\n", result); - return result; + netdev_err(wlandev->netdev, + "writeimage state enable failed w/ result=%d, " + "aborting download\n", result); + goto free_result; } - resultcode = rstatemsg.resultcode.data; + resultcode = rstmsg->resultcode.data; if (resultcode != P80211ENUM_resultcode_success) { - printk(KERN_ERR - "writeimage()->xxxdl_state msg indicates failure, " - "w/ resultcode=%d, aborting download.\n", resultcode); - return 1; + netdev_err(wlandev->netdev, + "writeimage()->xxxdl_state msg indicates failure, " + "w/ resultcode=%d, aborting download.\n", resultcode); + result = 1; + goto free_result; } /* Now, loop through the data chunks and send WRITESIZE_MAX data */ @@ -1045,17 +1058,18 @@ int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk, nwrites += (fchunk[i].len % WRITESIZE_MAX) ? 1 : 0; curroff = 0; for (j = 0; j < nwrites; j++) { - currlen = - (fchunk[i].len - (WRITESIZE_MAX * j)) > - WRITESIZE_MAX ? WRITESIZE_MAX : (fchunk[i].len - - (WRITESIZE_MAX * - j)); + /* TODO Move this to a separate function */ + int lenleft = fchunk[i].len - (WRITESIZE_MAX * j); + if (fchunk[i].len > WRITESIZE_MAX) + currlen = WRITESIZE_MAX; + else + currlen = lenleft; curroff = j * WRITESIZE_MAX; currdaddr = fchunk[i].addr + curroff; /* Setup the message */ - rwritemsg.addr.data = currdaddr; - rwritemsg.len.data = currlen; - memcpy(rwritemsg.data.data, + rwrmsg->addr.data = currdaddr; + rwrmsg->len.data = currlen; + memcpy(rwrmsg->data.data, fchunk[i].data + curroff, currlen); /* Send flashdl_write(pda) */ @@ -1063,23 +1077,22 @@ int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk, ("Sending xxxdl_write message addr=%06x len=%d.\n", currdaddr, currlen); - msgp = (p80211msg_t *) & rwritemsg; - result = prism2mgmt_ramdl_write(wlandev, msgp); + result = prism2mgmt_ramdl_write(wlandev, rwrmsg); /* Check the results */ if (result) { - printk(KERN_ERR - "writeimage chunk write failed w/ result=%d, " - "aborting download\n", result); - return result; + netdev_err(wlandev->netdev, + "writeimage chunk write failed w/ " + "result=%d, aborting download\n", result); + goto free_result; } - resultcode = rstatemsg.resultcode.data; + resultcode = rstmsg->resultcode.data; if (resultcode != P80211ENUM_resultcode_success) { - printk(KERN_ERR - "writeimage()->xxxdl_write msg indicates failure, " + pr_err("writeimage()->xxxdl_write msg indicates failure, " "w/ resultcode=%d, aborting download.\n", resultcode); - return 1; + result = 1; + goto free_result; } } @@ -1087,28 +1100,32 @@ int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk, /* Send xxx_state(disable) */ pr_debug("Sending dl_state(disable) message.\n"); - rstatemsg.enable.data = P80211ENUM_truth_false; - rstatemsg.exeaddr.data = 0; + rstmsg->enable.data = P80211ENUM_truth_false; + rstmsg->exeaddr.data = 0; - msgp = (p80211msg_t *) & rstatemsg; - result = prism2mgmt_ramdl_state(wlandev, msgp); + result = prism2mgmt_ramdl_state(wlandev, rstmsg); if (result) { - printk(KERN_ERR - "writeimage state disable failed w/ result=%d, " - "aborting download\n", result); - return result; + netdev_err(wlandev->netdev, + "writeimage state disable failed w/ result=%d, " + "aborting download\n", result); + goto free_result; } - resultcode = rstatemsg.resultcode.data; + resultcode = rstmsg->resultcode.data; if (resultcode != P80211ENUM_resultcode_success) { - printk(KERN_ERR - "writeimage()->xxxdl_state msg indicates failure, " - "w/ resultcode=%d, aborting download.\n", resultcode); - return 1; + netdev_err(wlandev->netdev, + "writeimage()->xxxdl_state msg indicates failure, " + "w/ resultcode=%d, aborting download.\n", resultcode); + result = 1; + goto free_result; } + +free_result: + kfree(rstmsg); + kfree(rwrmsg); return result; } -int validate_identity(void) +static int validate_identity(void) { int i; int result = 1; @@ -1161,7 +1178,7 @@ int validate_identity(void) /* SEC compat range */ if ((s3info[i].info.compat.role == 1) && (s3info[i].info.compat.id == 4)) { - + /* FIXME: isn't something missing here? */ } break; @@ -1196,8 +1213,9 @@ int validate_identity(void) pr_debug("Unknown inforec type %d\n", s3info[i].type); } } - // walk through + /* walk through */ - if (trump && (result != 2)) result = 0; + if (trump && (result != 2)) + result = 0; return result; } |
