firmware.h revision 1.6
11.6Sriastrad/* $NetBSD: firmware.h,v 1.6 2014/08/06 13:51:12 riastradh Exp $ */ 21.2Sriastrad 31.2Sriastrad/*- 41.2Sriastrad * Copyright (c) 2013 The NetBSD Foundation, Inc. 51.2Sriastrad * All rights reserved. 61.2Sriastrad * 71.2Sriastrad * This code is derived from software contributed to The NetBSD Foundation 81.2Sriastrad * by Taylor R. Campbell. 91.2Sriastrad * 101.2Sriastrad * Redistribution and use in source and binary forms, with or without 111.2Sriastrad * modification, are permitted provided that the following conditions 121.2Sriastrad * are met: 131.2Sriastrad * 1. Redistributions of source code must retain the above copyright 141.2Sriastrad * notice, this list of conditions and the following disclaimer. 151.2Sriastrad * 2. Redistributions in binary form must reproduce the above copyright 161.2Sriastrad * notice, this list of conditions and the following disclaimer in the 171.2Sriastrad * documentation and/or other materials provided with the distribution. 181.2Sriastrad * 191.2Sriastrad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 201.2Sriastrad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 211.2Sriastrad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 221.2Sriastrad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 231.2Sriastrad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 241.2Sriastrad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 251.2Sriastrad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 261.2Sriastrad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 271.2Sriastrad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 281.2Sriastrad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 291.2Sriastrad * POSSIBILITY OF SUCH DAMAGE. 301.2Sriastrad */ 311.2Sriastrad 321.2Sriastrad#ifndef _LINUX_FIRMWARE_H_ 331.2Sriastrad#define _LINUX_FIRMWARE_H_ 341.2Sriastrad 351.3Sriastrad#include <sys/types.h> 361.3Sriastrad#include <sys/device.h> 371.3Sriastrad#include <sys/kmem.h> 381.3Sriastrad#include <sys/systm.h> 391.3Sriastrad 401.3Sriastrad#include <dev/firmload.h> 411.3Sriastrad 421.3Sriastradstruct device; 431.3Sriastrad 441.3Sriastradstruct firmware { 451.3Sriastrad void *data; 461.3Sriastrad size_t size; 471.3Sriastrad}; 481.3Sriastrad 491.3Sriastradstatic inline int 501.3Sriastradrequest_firmware(const struct firmware **fwp, const char *image_name, 511.3Sriastrad struct device *dev) 521.3Sriastrad{ 531.5Sriastrad const char *drvname; 541.3Sriastrad struct firmware *fw; 551.6Sriastrad firmware_handle_t handle; 561.3Sriastrad int ret; 571.3Sriastrad 581.3Sriastrad fw = kmem_alloc(sizeof(*fw), KM_SLEEP); 591.3Sriastrad 601.5Sriastrad /* 611.5Sriastrad * If driver xyz(4) asks for xyz/foo/bar.bin, turn that into 621.5Sriastrad * just foo/bar.bin. This leaves open the possibility of name 631.5Sriastrad * collisions. Let's hope upstream is sensible about this. 641.5Sriastrad */ 651.5Sriastrad drvname = device_cfdriver(dev)->cd_name; 661.5Sriastrad if ((strncmp(drvname, image_name, strlen(drvname)) == 0) && 671.5Sriastrad (image_name[strlen(drvname)] == '/')) 681.5Sriastrad image_name += (strlen(drvname) + 1); 691.5Sriastrad 701.3Sriastrad /* XXX errno NetBSD->Linux */ 711.6Sriastrad ret = -firmware_open(drvname, image_name, &handle); 721.3Sriastrad if (ret) 731.3Sriastrad goto fail0; 741.6Sriastrad fw->size = firmware_get_size(handle); 751.3Sriastrad fw->data = firmware_malloc(fw->size); 761.3Sriastrad 771.3Sriastrad /* XXX errno NetBSD->Linux */ 781.6Sriastrad ret = -firmware_read(handle, 0, fw->data, fw->size); 791.6Sriastrad (void)firmware_close(handle); 801.3Sriastrad if (ret) 811.3Sriastrad goto fail1; 821.3Sriastrad 831.3Sriastrad /* Success! */ 841.3Sriastrad *fwp = fw; 851.3Sriastrad return 0; 861.3Sriastrad 871.3Sriastradfail1: firmware_free(fw->data, fw->size); 881.3Sriastradfail0: KASSERT(ret); 891.3Sriastrad kmem_free(fw, sizeof(*fw)); 901.4Sriastrad *fwp = NULL; 911.3Sriastrad return ret; 921.3Sriastrad} 931.3Sriastrad 941.3Sriastradstatic inline void 951.3Sriastradrelease_firmware(const struct firmware *fw) 961.3Sriastrad{ 971.3Sriastrad 981.4Sriastrad if (fw != NULL) { 991.4Sriastrad firmware_free(fw->data, fw->size); 1001.4Sriastrad kmem_free(__UNCONST(fw), sizeof(*fw)); 1011.4Sriastrad } 1021.3Sriastrad} 1031.3Sriastrad 1041.2Sriastrad#endif /* _LINUX_FIRMWARE_H_ */ 105