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