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