xref: /freebsd/sys/dev/ispfw/ispfw.c (revision b0c6b068)
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
41b0c6b068SJoerg Pulz #define	ISP_2600	1
42b0c6b068SJoerg Pulz #define	ISP_2700	1
43b0c6b068SJoerg 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
56b0c6b068SJoerg Pulz #if	defined(ISP_2600)
57b0c6b068SJoerg Pulz #include <dev/ispfw/asm_2600.h>
58b0c6b068SJoerg Pulz #endif
59b0c6b068SJoerg Pulz #if	defined(ISP_2700)
60b0c6b068SJoerg Pulz #include <dev/ispfw/asm_2700.h>
61b0c6b068SJoerg Pulz #endif
62b0c6b068SJoerg Pulz #if	defined(ISP_2800)
63b0c6b068SJoerg Pulz #include <dev/ispfw/asm_2800.h>
64b0c6b068SJoerg 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
72b0c6b068SJoerg Pulz #if	defined(ISP_2600)
73b0c6b068SJoerg Pulz static int	isp_2600_loaded;
74b0c6b068SJoerg Pulz #endif
75b0c6b068SJoerg Pulz #if	defined(ISP_2700)
76b0c6b068SJoerg Pulz static int	isp_2700_loaded;
77b0c6b068SJoerg Pulz #endif
78b0c6b068SJoerg Pulz #if	defined(ISP_2800)
79b0c6b068SJoerg Pulz static int	isp_2800_loaded;
80b0c6b068SJoerg 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
114b0c6b068SJoerg Pulz #if	defined(ISP_2600)
115b0c6b068SJoerg Pulz 	RMACRO(isp_2600);
116b0c6b068SJoerg Pulz #endif
117b0c6b068SJoerg Pulz #if	defined(ISP_2700)
118b0c6b068SJoerg Pulz 	RMACRO(isp_2700);
119b0c6b068SJoerg Pulz #endif
120b0c6b068SJoerg Pulz #if	defined(ISP_2800)
121b0c6b068SJoerg Pulz 	RMACRO(isp_2800);
122b0c6b068SJoerg 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
137b0c6b068SJoerg Pulz #if	defined(ISP_2600)
138b0c6b068SJoerg Pulz 	UMACRO(isp_2600);
139b0c6b068SJoerg Pulz #endif
140b0c6b068SJoerg Pulz #if	defined(ISP_2700)
141b0c6b068SJoerg Pulz 	UMACRO(isp_2700);
142b0c6b068SJoerg Pulz #endif
143b0c6b068SJoerg Pulz #if	defined(ISP_2800)
144b0c6b068SJoerg Pulz 	UMACRO(isp_2800);
145b0c6b068SJoerg 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);
170b0c6b068SJoerg Pulz #elif	defined(ISP_2600)
171b0c6b068SJoerg Pulz DECLARE_MODULE(isp_2600, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD);
172b0c6b068SJoerg Pulz #elif	defined(ISP_2700)
173b0c6b068SJoerg Pulz DECLARE_MODULE(isp_2700, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD);
174b0c6b068SJoerg Pulz #elif	defined(ISP_2800)
175b0c6b068SJoerg 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