xref: /freebsd/usr.sbin/bluetooth/ath3kfw/ath3k_fw.c (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
1*aebdb1e2SAdrian Chadd /*-
2*aebdb1e2SAdrian Chadd  * Copyright (c) 2013 Adrian Chadd <adrian@freebsd.org>
3*aebdb1e2SAdrian Chadd  * All rights reserved.
4*aebdb1e2SAdrian Chadd  *
5*aebdb1e2SAdrian Chadd  * Redistribution and use in source and binary forms, with or without
6*aebdb1e2SAdrian Chadd  * modification, are permitted provided that the following conditions
7*aebdb1e2SAdrian Chadd  * are met:
8*aebdb1e2SAdrian Chadd  * 1. Redistributions of source code must retain the above copyright
9*aebdb1e2SAdrian Chadd  *    notice, this list of conditions and the following disclaimer,
10*aebdb1e2SAdrian Chadd  *    without modification.
11*aebdb1e2SAdrian Chadd  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12*aebdb1e2SAdrian Chadd  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13*aebdb1e2SAdrian Chadd  *    redistribution must be conditioned upon including a substantially
14*aebdb1e2SAdrian Chadd  *    similar Disclaimer requirement for further binary redistribution.
15*aebdb1e2SAdrian Chadd  *
16*aebdb1e2SAdrian Chadd  * NO WARRANTY
17*aebdb1e2SAdrian Chadd  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*aebdb1e2SAdrian Chadd  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*aebdb1e2SAdrian Chadd  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20*aebdb1e2SAdrian Chadd  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21*aebdb1e2SAdrian Chadd  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22*aebdb1e2SAdrian Chadd  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23*aebdb1e2SAdrian Chadd  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24*aebdb1e2SAdrian Chadd  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25*aebdb1e2SAdrian Chadd  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26*aebdb1e2SAdrian Chadd  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27*aebdb1e2SAdrian Chadd  * THE POSSIBILITY OF SUCH DAMAGES.
28*aebdb1e2SAdrian Chadd  */
29*aebdb1e2SAdrian Chadd 
30*aebdb1e2SAdrian Chadd #include <stdio.h>
31*aebdb1e2SAdrian Chadd #include <stdlib.h>
32*aebdb1e2SAdrian Chadd #include <unistd.h>
33*aebdb1e2SAdrian Chadd #include <errno.h>
34*aebdb1e2SAdrian Chadd #include <string.h>
35*aebdb1e2SAdrian Chadd #include <err.h>
36*aebdb1e2SAdrian Chadd #include <fcntl.h>
37*aebdb1e2SAdrian Chadd #include <sys/types.h>
38*aebdb1e2SAdrian Chadd #include <sys/stat.h>
39*aebdb1e2SAdrian Chadd 
40*aebdb1e2SAdrian Chadd #include "ath3k_fw.h"
41*aebdb1e2SAdrian Chadd #include "ath3k_dbg.h"
42*aebdb1e2SAdrian Chadd 
43*aebdb1e2SAdrian Chadd int
ath3k_fw_read(struct ath3k_firmware * fw,const char * fwname)44*aebdb1e2SAdrian Chadd ath3k_fw_read(struct ath3k_firmware *fw, const char *fwname)
45*aebdb1e2SAdrian Chadd {
46*aebdb1e2SAdrian Chadd 	int fd;
47*aebdb1e2SAdrian Chadd 	struct stat sb;
48*aebdb1e2SAdrian Chadd 	unsigned char *buf;
49*aebdb1e2SAdrian Chadd 	ssize_t r;
50*aebdb1e2SAdrian Chadd 
51*aebdb1e2SAdrian Chadd 	fd = open(fwname, O_RDONLY);
52*aebdb1e2SAdrian Chadd 	if (fd < 0) {
53*aebdb1e2SAdrian Chadd 		warn("%s: open: %s", __func__, fwname);
54*aebdb1e2SAdrian Chadd 		return (0);
55*aebdb1e2SAdrian Chadd 	}
56*aebdb1e2SAdrian Chadd 
57*aebdb1e2SAdrian Chadd 	if (fstat(fd, &sb) != 0) {
58*aebdb1e2SAdrian Chadd 		warn("%s: stat: %s", __func__, fwname);
59*aebdb1e2SAdrian Chadd 		close(fd);
60*aebdb1e2SAdrian Chadd 		return (0);
61*aebdb1e2SAdrian Chadd 	}
62*aebdb1e2SAdrian Chadd 
63*aebdb1e2SAdrian Chadd 	buf = calloc(1, sb.st_size);
64*aebdb1e2SAdrian Chadd 	if (buf == NULL) {
65*aebdb1e2SAdrian Chadd 		warn("%s: calloc", __func__);
66*aebdb1e2SAdrian Chadd 		close(fd);
67*aebdb1e2SAdrian Chadd 		return (0);
68*aebdb1e2SAdrian Chadd 	}
69*aebdb1e2SAdrian Chadd 
70*aebdb1e2SAdrian Chadd 	/* XXX handle partial reads */
71*aebdb1e2SAdrian Chadd 	r = read(fd, buf, sb.st_size);
72*aebdb1e2SAdrian Chadd 	if (r < 0) {
73*aebdb1e2SAdrian Chadd 		warn("%s: read", __func__);
74*aebdb1e2SAdrian Chadd 		free(buf);
75*aebdb1e2SAdrian Chadd 		close(fd);
76*aebdb1e2SAdrian Chadd 		return (0);
77*aebdb1e2SAdrian Chadd 	}
78*aebdb1e2SAdrian Chadd 
79*aebdb1e2SAdrian Chadd 	if (r != sb.st_size) {
80*aebdb1e2SAdrian Chadd 		fprintf(stderr, "%s: read len %d != file size %d\n",
81*aebdb1e2SAdrian Chadd 		    __func__,
82*aebdb1e2SAdrian Chadd 		    (int) r,
83*aebdb1e2SAdrian Chadd 		    (int) sb.st_size);
84*aebdb1e2SAdrian Chadd 		free(buf);
85*aebdb1e2SAdrian Chadd 		close(fd);
86*aebdb1e2SAdrian Chadd 		return (0);
87*aebdb1e2SAdrian Chadd 	}
88*aebdb1e2SAdrian Chadd 
89*aebdb1e2SAdrian Chadd 	/* We have everything, so! */
90*aebdb1e2SAdrian Chadd 
91*aebdb1e2SAdrian Chadd 	bzero(fw, sizeof(*fw));
92*aebdb1e2SAdrian Chadd 
93*aebdb1e2SAdrian Chadd 	fw->fwname = strdup(fwname);
94*aebdb1e2SAdrian Chadd 	fw->len = sb.st_size;
95*aebdb1e2SAdrian Chadd 	fw->size = sb.st_size;
96*aebdb1e2SAdrian Chadd 	fw->buf = buf;
97*aebdb1e2SAdrian Chadd 
98*aebdb1e2SAdrian Chadd 	close(fd);
99*aebdb1e2SAdrian Chadd 	return (1);
100*aebdb1e2SAdrian Chadd }
101*aebdb1e2SAdrian Chadd 
102*aebdb1e2SAdrian Chadd void
ath3k_fw_free(struct ath3k_firmware * fw)103*aebdb1e2SAdrian Chadd ath3k_fw_free(struct ath3k_firmware *fw)
104*aebdb1e2SAdrian Chadd {
105*aebdb1e2SAdrian Chadd 	if (fw->fwname)
106*aebdb1e2SAdrian Chadd 		free(fw->fwname);
107*aebdb1e2SAdrian Chadd 	if (fw->buf)
108*aebdb1e2SAdrian Chadd 		free(fw->buf);
109*aebdb1e2SAdrian Chadd 	bzero(fw, sizeof(*fw));
110*aebdb1e2SAdrian Chadd }
111