1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * ISP Firmware Modules for FreeBSD 5 * 6 * Copyright (c) 2000, 2001, 2006 by Matthew Jacob 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice immediately at the beginning of the file, without modification, 14 * this list of conditions, and the following disclaimer. 15 * 2. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #include <sys/param.h> 32 #include <sys/firmware.h> 33 #include <sys/kernel.h> 34 #include <sys/linker.h> 35 #include <sys/module.h> 36 #include <sys/systm.h> 37 38 #if defined(ISP_ALL) || !defined(KLD_MODULE) 39 #define ISP_2400 1 40 #define ISP_2500 1 41 #define ISP_2600 1 42 #define ISP_2700 1 43 #define ISP_2800 1 44 #endif 45 46 #ifndef MODULE_NAME 47 #define MODULE_NAME "ispfw" 48 #endif 49 50 #if defined(ISP_2400) 51 #include <dev/ispfw/asm_2400.h> 52 #endif 53 #if defined(ISP_2500) 54 #include <dev/ispfw/asm_2500.h> 55 #endif 56 #if defined(ISP_2600) 57 #include <dev/ispfw/asm_2600.h> 58 #endif 59 #if defined(ISP_2700) 60 #include <dev/ispfw/asm_2700.h> 61 #endif 62 #if defined(ISP_2800) 63 #include <dev/ispfw/asm_2800.h> 64 #endif 65 66 #if defined(ISP_2400) 67 static int isp_2400_loaded; 68 #endif 69 #if defined(ISP_2500) 70 static int isp_2500_loaded; 71 #endif 72 #if defined(ISP_2600) 73 static int isp_2600_loaded; 74 #endif 75 #if defined(ISP_2700) 76 static int isp_2700_loaded; 77 #endif 78 #if defined(ISP_2800) 79 static int isp_2800_loaded; 80 #endif 81 82 #define ISPFW_VERSION 1 83 84 #define RMACRO(token) do { \ 85 if (token##_loaded) \ 86 break; \ 87 if (firmware_register(#token, token##_risc_code, \ 88 token##_risc_code[3] * sizeof(token##_risc_code[3]), \ 89 ISPFW_VERSION, NULL) == NULL) \ 90 break; \ 91 token##_loaded++; \ 92 } while (0) 93 94 #define UMACRO(token) do { \ 95 if (!token##_loaded) \ 96 break; \ 97 if (firmware_unregister(#token) != 0) { \ 98 error = EBUSY; \ 99 break; \ 100 } \ 101 token##_loaded--; \ 102 } while (0) 103 104 static int 105 do_load_fw(void) 106 { 107 108 #if defined(ISP_2400) 109 RMACRO(isp_2400); 110 #endif 111 #if defined(ISP_2500) 112 RMACRO(isp_2500); 113 #endif 114 #if defined(ISP_2600) 115 RMACRO(isp_2600); 116 #endif 117 #if defined(ISP_2700) 118 RMACRO(isp_2700); 119 #endif 120 #if defined(ISP_2800) 121 RMACRO(isp_2800); 122 #endif 123 return (0); 124 } 125 126 static int 127 do_unload_fw(void) 128 { 129 int error = 0; 130 131 #if defined(ISP_2400) 132 UMACRO(isp_2400); 133 #endif 134 #if defined(ISP_2500) 135 UMACRO(isp_2500); 136 #endif 137 #if defined(ISP_2600) 138 UMACRO(isp_2600); 139 #endif 140 #if defined(ISP_2700) 141 UMACRO(isp_2700); 142 #endif 143 #if defined(ISP_2800) 144 UMACRO(isp_2800); 145 #endif 146 return (error); 147 } 148 149 static int 150 module_handler(module_t mod, int what, void *arg) 151 { 152 153 switch (what) { 154 case MOD_LOAD: 155 return (do_load_fw()); 156 case MOD_UNLOAD: 157 return (do_unload_fw()); 158 } 159 return (EOPNOTSUPP); 160 } 161 static moduledata_t ispfw_mod = { 162 MODULE_NAME, module_handler, NULL 163 }; 164 #if defined(ISP_ALL) || !defined(KLD_MODULE) 165 DECLARE_MODULE(ispfw, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD); 166 #elif defined(ISP_2400) 167 DECLARE_MODULE(isp_2400, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD); 168 #elif defined(ISP_2500) 169 DECLARE_MODULE(isp_2500, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD); 170 #elif defined(ISP_2600) 171 DECLARE_MODULE(isp_2600, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD); 172 #elif defined(ISP_2700) 173 DECLARE_MODULE(isp_2700, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD); 174 #elif defined(ISP_2800) 175 DECLARE_MODULE(isp_2800, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD); 176 #else 177 #error "firmware not specified" 178 #endif 179