]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ispfw/ispfw.c
Use __FBSDID().
[FreeBSD/FreeBSD.git] / sys / dev / ispfw / ispfw.c
1 /*
2
3 #include <sys/cdefs.h>
4 __FBSDID("$FreeBSD$");
5  * ISP Firmware Helper Pseudo Device for FreeBSD
6  *
7  * Copyright (c) 2000, 2001, by Matthew Jacob
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice immediately at the beginning of the file, without modification,
15  *    this list of conditions, and the following disclaimer.
16  * 2. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31
32 #include <sys/param.h>
33 #include <sys/kernel.h>
34 #include <sys/malloc.h>
35
36 #include <dev/ispfw/asm_1040.h>
37 #include <dev/ispfw/asm_1080.h>
38 #include <dev/ispfw/asm_12160.h>
39 #include <dev/ispfw/asm_2100.h>
40 #include <dev/ispfw/asm_2200.h>
41 #include <dev/ispfw/asm_2300.h>
42 #if     _MACHINE_ARCH == sparc64
43 #include <dev/ispfw/asm_1000.h>
44 #endif
45
46 #define ISPFW_VERSION   0
47
48 #define PCI_PRODUCT_QLOGIC_ISP1020      0x1020
49 #define PCI_PRODUCT_QLOGIC_ISP1080      0x1080
50 #define PCI_PRODUCT_QLOGIC_ISP10160     0x1016
51 #define PCI_PRODUCT_QLOGIC_ISP12160     0x1216
52 #define PCI_PRODUCT_QLOGIC_ISP1240      0x1240
53 #define PCI_PRODUCT_QLOGIC_ISP1280      0x1280
54 #define PCI_PRODUCT_QLOGIC_ISP2100      0x2100
55 #define PCI_PRODUCT_QLOGIC_ISP2200      0x2200
56 #define PCI_PRODUCT_QLOGIC_ISP2300      0x2300
57 #define PCI_PRODUCT_QLOGIC_ISP2312      0x2312
58 #if     _MACHINE_ARCH == sparc64
59 #define SBUS_PRODUCT_QLOGIC_ISP1000     0x1000
60 #endif
61
62 typedef void ispfwfunc(int, int, int, const u_int16_t **);
63 extern ispfwfunc *isp_get_firmware_p;
64 static void isp_get_firmware(int, int, int, const u_int16_t **);
65
66 static int ncallers = 0;
67 static const u_int16_t ***callp = NULL;
68 static int addcaller(const u_int16_t **);
69
70 static int
71 addcaller(const u_int16_t **caller)
72 {
73         const u_int16_t ***newcallp;
74         int i;
75         for (i = 0; i < ncallers; i++) {
76                 if (callp[i] == caller)
77                         return (1);
78         }
79         newcallp = malloc((ncallers + 1) * sizeof (const u_int16_t ***),
80             M_DEVBUF, M_NOWAIT);
81         if (newcallp == NULL) {
82                 return (0);
83         }
84         for (i = 0; i < ncallers; i++) {
85                 newcallp[i] = callp[i];
86         }
87         newcallp[ncallers] = caller;
88         if (ncallers++)
89                 free(callp, M_DEVBUF);
90         callp = newcallp;
91         return (1);
92 }
93
94 static void
95 isp_get_firmware(int version, int tgtmode, int devid, const u_int16_t **ptrp)
96 {
97         const u_int16_t *rp = NULL;
98
99         if (version == ISPFW_VERSION) {
100                 switch (devid) {
101                 case PCI_PRODUCT_QLOGIC_ISP1020:
102                         if (tgtmode)
103                                 rp = isp_1040_risc_code_it;
104                         else
105                                 rp = isp_1040_risc_code;
106                         break;
107                 case PCI_PRODUCT_QLOGIC_ISP1080:
108                 case PCI_PRODUCT_QLOGIC_ISP1240:
109                 case PCI_PRODUCT_QLOGIC_ISP1280:
110                         if (tgtmode)
111                                 rp = isp_1080_risc_code_it;
112                         else
113                                 rp = isp_1080_risc_code;
114                         break;
115                 case PCI_PRODUCT_QLOGIC_ISP10160:
116                 case PCI_PRODUCT_QLOGIC_ISP12160:
117                         if (tgtmode)
118                                 rp = isp_12160_risc_code_it;
119                         else
120                                 rp = isp_12160_risc_code;
121                         break;
122                 case PCI_PRODUCT_QLOGIC_ISP2100:
123                         rp = isp_2100_risc_code;
124                         break;
125                 case PCI_PRODUCT_QLOGIC_ISP2200:
126                         rp = isp_2200_risc_code;
127                         break;
128                 case PCI_PRODUCT_QLOGIC_ISP2300:
129                 case PCI_PRODUCT_QLOGIC_ISP2312:
130                         rp = isp_2300_risc_code;
131                         break;
132 #if     _MACHINE_ARCH == sparc64
133                 case SBUS_PRODUCT_QLOGIC_ISP1000:
134                         if (tgtmode)
135                                 break;
136                         rp = isp_1000_risc_code;
137                         break;
138 #endif
139                 default:
140                         break;
141                 }
142         }
143         if (rp && addcaller(ptrp)) {
144                 *ptrp = rp;
145         }
146 }
147
148 static int
149 isp_module_handler(module_t mod, int what, void *arg)
150 {
151         switch (what) {
152         case MOD_LOAD:
153                 isp_get_firmware_p = isp_get_firmware;
154                 break;
155         case MOD_UNLOAD:
156                 isp_get_firmware_p = NULL;
157                 if (ncallers)  {
158                         int i;
159                         for (i = 0; i < ncallers; i++) {
160                                 *callp[i] = NULL;
161                         }
162                         free(callp, M_DEVBUF);
163                 }
164                 break;
165         default:
166                 break;
167         }
168         return (0);
169 }
170 static moduledata_t ispfw_mod = {
171         "ispfw", isp_module_handler, NULL
172 };
173 DECLARE_MODULE(ispfw, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD);
174 MODULE_VERSION(ispfw, ISPFW_VERSION);
175 MODULE_DEPEND(ispfw, isp, 1, 1, 1);