1301537Sadrian/*-
2301537Sadrian * Copyright (c) 2013 Adrian Chadd <adrian@freebsd.org>
3301537Sadrian * All rights reserved.
4301537Sadrian *
5301537Sadrian * Redistribution and use in source and binary forms, with or without
6301537Sadrian * modification, are permitted provided that the following conditions
7301537Sadrian * are met:
8301537Sadrian * 1. Redistributions of source code must retain the above copyright
9301537Sadrian *    notice, this list of conditions and the following disclaimer,
10301537Sadrian *    without modification.
11301537Sadrian * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12301537Sadrian *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13301537Sadrian *    redistribution must be conditioned upon including a substantially
14301537Sadrian *    similar Disclaimer requirement for further binary redistribution.
15301537Sadrian *
16301537Sadrian * NO WARRANTY
17301537Sadrian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18301537Sadrian * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19301537Sadrian * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20301537Sadrian * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21301537Sadrian * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22301537Sadrian * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23301537Sadrian * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24301537Sadrian * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25301537Sadrian * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26301537Sadrian * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27301537Sadrian * THE POSSIBILITY OF SUCH DAMAGES.
28301537Sadrian *
29301537Sadrian * $FreeBSD$
30301537Sadrian */
31301537Sadrian
32301537Sadrian#include <stdio.h>
33301537Sadrian#include <stdlib.h>
34301537Sadrian#include <unistd.h>
35301537Sadrian#include <errno.h>
36301537Sadrian#include <string.h>
37301537Sadrian#include <err.h>
38301537Sadrian#include <fcntl.h>
39301537Sadrian#include <sys/types.h>
40301537Sadrian#include <sys/stat.h>
41301537Sadrian
42301537Sadrian#include "ath3k_fw.h"
43301537Sadrian#include "ath3k_dbg.h"
44301537Sadrian
45301537Sadrianint
46301537Sadrianath3k_fw_read(struct ath3k_firmware *fw, const char *fwname)
47301537Sadrian{
48301537Sadrian	int fd;
49301537Sadrian	struct stat sb;
50301537Sadrian	unsigned char *buf;
51301537Sadrian	ssize_t r;
52301537Sadrian	int i;
53301537Sadrian
54301537Sadrian	fd = open(fwname, O_RDONLY);
55301537Sadrian	if (fd < 0) {
56301537Sadrian		warn("%s: open: %s", __func__, fwname);
57301537Sadrian		return (0);
58301537Sadrian	}
59301537Sadrian
60301537Sadrian	if (fstat(fd, &sb) != 0) {
61301537Sadrian		warn("%s: stat: %s", __func__, fwname);
62301537Sadrian		close(fd);
63301537Sadrian		return (0);
64301537Sadrian	}
65301537Sadrian
66301537Sadrian	buf = calloc(1, sb.st_size);
67301537Sadrian	if (buf == NULL) {
68301537Sadrian		warn("%s: calloc", __func__);
69301537Sadrian		close(fd);
70301537Sadrian		return (0);
71301537Sadrian	}
72301537Sadrian
73301537Sadrian	i = 0;
74301537Sadrian	/* XXX handle partial reads */
75301537Sadrian	r = read(fd, buf, sb.st_size);
76301537Sadrian	if (r < 0) {
77301537Sadrian		warn("%s: read", __func__);
78301537Sadrian		free(buf);
79301537Sadrian		close(fd);
80301537Sadrian		return (0);
81301537Sadrian	}
82301537Sadrian
83301537Sadrian	if (r != sb.st_size) {
84301537Sadrian		fprintf(stderr, "%s: read len %d != file size %d\n",
85301537Sadrian		    __func__,
86301537Sadrian		    (int) r,
87301537Sadrian		    (int) sb.st_size);
88301537Sadrian		free(buf);
89301537Sadrian		close(fd);
90301537Sadrian		return (0);
91301537Sadrian	}
92301537Sadrian
93301537Sadrian	/* We have everything, so! */
94301537Sadrian
95301537Sadrian	bzero(fw, sizeof(*fw));
96301537Sadrian
97301537Sadrian	fw->fwname = strdup(fwname);
98301537Sadrian	fw->len = sb.st_size;
99301537Sadrian	fw->size = sb.st_size;
100301537Sadrian	fw->buf = buf;
101301537Sadrian
102301537Sadrian	close(fd);
103301537Sadrian	return (1);
104301537Sadrian}
105301537Sadrian
106301537Sadrianvoid
107301537Sadrianath3k_fw_free(struct ath3k_firmware *fw)
108301537Sadrian{
109301537Sadrian	if (fw->fwname)
110301537Sadrian		free(fw->fwname);
111301537Sadrian	if (fw->buf)
112301537Sadrian		free(fw->buf);
113301537Sadrian	bzero(fw, sizeof(*fw));
114301537Sadrian}
115