summaryrefslogtreecommitdiffstats
path: root/sys/dev/ispfw
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2006-07-09 17:50:20 +0000
committermjacob <mjacob@FreeBSD.org>2006-07-09 17:50:20 +0000
commita6dea567ad2965b9db76644f687e9f9e987be2ff (patch)
tree02927e03d3704d09891594870139269cd8f3c287 /sys/dev/ispfw
parent685013634879c9cf1799d85237fd981587e51745 (diff)
downloadFreeBSD-src-a6dea567ad2965b9db76644f687e9f9e987be2ff.zip
FreeBSD-src-a6dea567ad2965b9db76644f687e9f9e987be2ff.tar.gz
Convert isp(4) and ispfw(4) to use firmware(9) to manage firmware
loading for the QLogic cards. Because isp(4) exists before the root is mounted, it's not really possible for us to use the kernel's linker to load modules directly from disk- that's really too bad. However, the this is still a net win in in that the firmware has been split up on a per chip (and in some cases, functionality) basis, so the amount of stuff loaded *can* be substantially less than the 1.5MB of firmware images that ispfw now manages. That is, each specific f/w set is now also built as a module. For example, QLogic 2322 f/w is built as isp_2322.ko and Initiator/Target 1080 firmware is built as isp_1080_it.ko. For compatibility purposes (i.e., to perturb folks the least), we also still build all of the firmware as one ispfw.ko module. This allows us to let 'ispfw_LOAD' keep on working in existing loader.conf files. If you now want to strip this down to just the firmware for your h/w, you can then change loader.conf to load the f/w you specifically want. We also still allow for ispfw to be statically built (e.g., for PAE and sparc64). Future changes will look at f/w unloading and also role switching that then uses the kernel linker to load different ips f/w sets. MFC after: 2 months
Diffstat (limited to 'sys/dev/ispfw')
-rw-r--r--sys/dev/ispfw/asm_1040.h6
-rw-r--r--sys/dev/ispfw/asm_1080.h7
-rw-r--r--sys/dev/ispfw/asm_12160.h6
-rw-r--r--sys/dev/ispfw/ispfw.c263
4 files changed, 159 insertions, 123 deletions
diff --git a/sys/dev/ispfw/asm_1040.h b/sys/dev/ispfw/asm_1040.h
index 9e78a56..3be21f1 100644
--- a/sys/dev/ispfw/asm_1040.h
+++ b/sys/dev/ispfw/asm_1040.h
@@ -34,6 +34,7 @@
/*
* Firmware Version 4.66.00 (14:49 Sep 05, 2000)
*/
+#ifdef ISP_1040
static const u_int16_t isp_1040_risc_code[] = {
0x0078, 0x1041, 0x0000, 0x2cd0, 0x0000, 0x2043, 0x4f50, 0x5952,
0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31,
@@ -1470,6 +1471,7 @@ static const u_int16_t isp_1040_risc_code[] = {
0x0040, 0x3cc6, 0x20a9, 0x0100, 0x0078, 0x3caf, 0x2009, 0x3d51,
0x200b, 0x3d7f, 0x2009, 0x3d50, 0x200b, 0x0000, 0x007c, 0x4de2
};
+#endif
/************************************************************************
* *
* --- ISP1040 Initiator/Target Firmware --- *
@@ -1479,7 +1481,8 @@ static const u_int16_t isp_1040_risc_code[] = {
/*
* Firmware Version 7.65.00 (14:17 Jul 20, 1999)
*/
-static const u_int16_t isp_1040_risc_code_it[] = {
+#ifdef ISP_1040_IT
+static const u_int16_t isp_1040_it_risc_code[] = {
0x0078, 0x103a, 0x0000, 0x4057, 0x0000, 0x2043, 0x4f50, 0x5952,
0x4947, 0x4854, 0x2031, 0x3939, 0x3520, 0x514c, 0x4f47, 0x4943,
0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350,
@@ -3540,3 +3543,4 @@ static const u_int16_t isp_1040_risc_code_it[] = {
0x0014, 0x878e, 0x0016, 0xa21c, 0x1035, 0xa8af, 0xa210, 0x3807,
0x300c, 0x817e, 0x872b, 0x8772, 0xa8a8, 0x0000, 0xdf21
};
+#endif
diff --git a/sys/dev/ispfw/asm_1080.h b/sys/dev/ispfw/asm_1080.h
index edb0ad7..8f4664c 100644
--- a/sys/dev/ispfw/asm_1080.h
+++ b/sys/dev/ispfw/asm_1080.h
@@ -34,6 +34,7 @@
/*
* Firmware Version 8.15.00 (14:35 Aug 22, 2000)
*/
+#ifdef ISP_1080
static const u_int16_t isp_1080_risc_code[] = {
0x0078, 0x1041, 0x0000, 0x3d3b, 0x0000, 0x2043, 0x4f50, 0x5952,
0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31,
@@ -1996,6 +1997,7 @@ static const u_int16_t isp_1080_risc_code[] = {
0x4cee, 0x7804, 0xd08c, 0x0040, 0x4d37, 0x681f, 0x000c, 0x70a0,
0x70a2, 0x007c, 0x205b
};
+#endif
/************************************************************************
* *
* --- ISP1240/ISP1080/ISP1280 Initiator/Target Firmware --- *
@@ -2005,8 +2007,8 @@ static const u_int16_t isp_1080_risc_code[] = {
/*
* Firmware Version 9.11.01 (15:46 May 23, 2000)
*/
-
-static const u_int16_t isp_1080_risc_code_it[] = {
+#ifdef ISP_1080_IT
+static const u_int16_t isp_1080_it_risc_code[] = {
0x0078, 0x103a, 0x0000, 0x4f62, 0x0000, 0x2043, 0x4f50, 0x5952,
0x4947, 0x4854, 0x2031, 0x3939, 0x3520, 0x514c, 0x4f47, 0x4943,
0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350,
@@ -4549,3 +4551,4 @@ static const u_int16_t isp_1080_risc_code_it[] = {
0xa8bb, 0xa210, 0x3807, 0x300c, 0x817e, 0x872b, 0x8772, 0x0014,
0x0000, 0xd27a
};
+#endif
diff --git a/sys/dev/ispfw/asm_12160.h b/sys/dev/ispfw/asm_12160.h
index bc1d420..4f5fbd0 100644
--- a/sys/dev/ispfw/asm_12160.h
+++ b/sys/dev/ispfw/asm_12160.h
@@ -34,6 +34,7 @@
/*
* Firmware Version 10.04.41 (10:30 Mar 21, 2003)
*/
+#ifdef ISP_12160
static const u_int16_t isp_12160_risc_code[] = {
0x0804, 0x1041, 0x0000, 0x36c9, 0x0000, 0x2043, 0x4f50, 0x5952,
0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31,
@@ -1790,10 +1791,12 @@ static const u_int16_t isp_12160_risc_code[] = {
0x0018, 0x00ce, 0x681f, 0x000c, 0x001e, 0x70a0, 0x70a2, 0x0005,
0x0c28
};
+#endif
/*
* Firmware Version 11.12.19 (17:10 Oct 25, 2001)
*/
-static const u_int16_t isp_12160_risc_code_it[] = {
+#ifdef ISP_12160_IT
+static const u_int16_t isp_12160_it_risc_code[] = {
0x0804, 0x103a, 0x0000, 0x4f4e, 0x0000, 0x2043, 0x4f50, 0x5952,
0x4947, 0x4854, 0x2031, 0x3939, 0x3520, 0x514c, 0x4f47, 0x4943,
0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350,
@@ -4333,3 +4336,4 @@ static const u_int16_t isp_12160_risc_code_it[] = {
0x9521, 0x85a1, 0x806f, 0x9422, 0x84a2, 0x80fd, 0x9405, 0x8485,
0x7021, 0x0014, 0xa300, 0xa8ca, 0x0000, 0x7a3c
};
+#endif
diff --git a/sys/dev/ispfw/ispfw.c b/sys/dev/ispfw/ispfw.c
index 01b8fcc..d45624b 100644
--- a/sys/dev/ispfw/ispfw.c
+++ b/sys/dev/ispfw/ispfw.c
@@ -1,7 +1,7 @@
/*-
- * ISP Firmware Helper Pseudo Device for FreeBSD
+ * ISP Firmware Modules for FreeBSD
*
- * Copyright (c) 2000, 2001, by Matthew Jacob
+ * Copyright (c) 2000, 2001, 2006 by Matthew Jacob
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,154 +31,179 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
-#include <sys/malloc.h>
#include <sys/module.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/linker.h>
+#include <sys/firmware.h>
+
+#if defined(ISP_ALL) || !defined(KLD_MODULE)
+#define ISP_1040 1
+#define ISP_1040_IT 1
+#define ISP_1080 1
+#define ISP_1080_IT 1
+#define ISP_12160 1
+#define ISP_12160_IT 1
+#define ISP_2100 1
+#define ISP_2200 1
+#define ISP_2300 1
+#define ISP_2322 1
+#ifdef __sparc64__
+#define ISP_1000 1
+#endif
+#define MODULE_NAME "isp"
+#endif
+#if defined(ISP_1040) || defined(ISP_1040_IT)
#include <dev/ispfw/asm_1040.h>
+#endif
+#if defined(ISP_1080) || defined(ISP_1080_IT)
#include <dev/ispfw/asm_1080.h>
+#endif
+#if defined(ISP_12160) || defined(ISP_12160_IT)
#include <dev/ispfw/asm_12160.h>
+#endif
+#if defined(ISP_2100)
#include <dev/ispfw/asm_2100.h>
+#endif
+#if defined(ISP_2200)
#include <dev/ispfw/asm_2200.h>
+#endif
+#if defined(ISP_2300)
#include <dev/ispfw/asm_2300.h>
+#endif
+#if defined(ISP_2322)
#include <dev/ispfw/asm_2322.h>
-#ifdef __sparc64__
-#include <dev/ispfw/asm_1000.h>
#endif
-
-#define ISPFW_VERSION 0
-
-#define PCI_PRODUCT_QLOGIC_ISP1020 0x1020
-#define PCI_PRODUCT_QLOGIC_ISP1080 0x1080
-#define PCI_PRODUCT_QLOGIC_ISP10160 0x1016
-#define PCI_PRODUCT_QLOGIC_ISP12160 0x1216
-#define PCI_PRODUCT_QLOGIC_ISP1240 0x1240
-#define PCI_PRODUCT_QLOGIC_ISP1280 0x1280
-#define PCI_PRODUCT_QLOGIC_ISP2100 0x2100
-#define PCI_PRODUCT_QLOGIC_ISP2200 0x2200
-#define PCI_PRODUCT_QLOGIC_ISP2300 0x2300
-#define PCI_PRODUCT_QLOGIC_ISP2312 0x2312
-#define PCI_PRODUCT_QLOGIC_ISP2322 0x2322
-#define PCI_PRODUCT_QLOGIC_ISP6312 0x6312
-#ifdef __sparc64__
-#define SBUS_PRODUCT_QLOGIC_ISP1000 0x1000
+#if defined(ISP_1000)
+#include <dev/ispfw/asm_1000.h>
#endif
-typedef void ispfwfunc(int, int, int, const u_int16_t **);
-extern ispfwfunc *isp_get_firmware_p;
-static void isp_get_firmware(int, int, int, const u_int16_t **);
+#define ISPFW_VERSION 1
+#define RMACRO(token) \
+ if (firmware_register(#token, token##_risc_code, \
+ token##_risc_code [3] << 1, ISPFW_VERSION, NULL) == NULL) { \
+ printf("unable to register firmware '%s'\n", #token); \
+ } else { \
+ printf("registered firmware set <%s>\n", #token); \
+ }
-static int ncallers = 0;
-static const u_int16_t ***callp = NULL;
-static int addcaller(const u_int16_t **);
+#define UMACRO(token) \
+ firmware_unregister(#token); \
+ printf("unregistered firmware set <%s>\n", #token);
static int
-addcaller(const u_int16_t **caller)
+do_load_fw(void)
{
- const u_int16_t ***newcallp;
- int i;
- for (i = 0; i < ncallers; i++) {
- if (callp[i] == caller)
- return (1);
- }
- newcallp = malloc((ncallers + 1) * sizeof (const u_int16_t ***),
- M_DEVBUF, M_NOWAIT);
- if (newcallp == NULL) {
- return (0);
- }
- for (i = 0; i < ncallers; i++) {
- newcallp[i] = callp[i];
- }
- newcallp[ncallers] = caller;
- if (ncallers++)
- free(callp, M_DEVBUF);
- callp = newcallp;
- return (1);
+#if defined(ISP_1000)
+ RMACRO(isp_1000);
+#endif
+#if defined(ISP_1040)
+ RMACRO(isp_1040);
+#endif
+#if defined(ISP_1040_IT)
+ RMACRO(isp_1040_it);
+#endif
+#if defined(ISP_1080)
+ RMACRO(isp_1080);
+#endif
+#if defined(ISP_1080_IT)
+ RMACRO(isp_1080_it);
+#endif
+#if defined(ISP_12160)
+ RMACRO(isp_12160);
+#endif
+#if defined(ISP_12160_IT)
+ RMACRO(isp_12160_it);
+#endif
+#if defined(ISP_2100)
+ RMACRO(isp_2100);
+#endif
+#if defined(ISP_2200)
+ RMACRO(isp_2200);
+#endif
+#if defined(ISP_2300)
+ RMACRO(isp_2300);
+#endif
+#if defined(ISP_2322)
+ RMACRO(isp_2322);
+#endif
+ return (0);
}
-static void
-isp_get_firmware(int version, int tgtmode, int devid, const u_int16_t **ptrp)
+static int
+do_unload_fw(void)
{
- const u_int16_t *rp = NULL;
-
- if (version == ISPFW_VERSION) {
- switch (devid) {
- case PCI_PRODUCT_QLOGIC_ISP1020:
- if (tgtmode)
- rp = isp_1040_risc_code_it;
- else
- rp = isp_1040_risc_code;
- break;
- case PCI_PRODUCT_QLOGIC_ISP1080:
- case PCI_PRODUCT_QLOGIC_ISP1240:
- case PCI_PRODUCT_QLOGIC_ISP1280:
- if (tgtmode)
- rp = isp_1080_risc_code_it;
- else
- rp = isp_1080_risc_code;
- break;
- case PCI_PRODUCT_QLOGIC_ISP10160:
- case PCI_PRODUCT_QLOGIC_ISP12160:
- if (tgtmode)
- rp = isp_12160_risc_code_it;
- else
- rp = isp_12160_risc_code;
- break;
- case PCI_PRODUCT_QLOGIC_ISP2100:
- rp = isp_2100_risc_code;
- break;
- case PCI_PRODUCT_QLOGIC_ISP2200:
- rp = isp_2200_risc_code;
- break;
- case PCI_PRODUCT_QLOGIC_ISP2300:
- case PCI_PRODUCT_QLOGIC_ISP2312:
- case PCI_PRODUCT_QLOGIC_ISP6312:
- rp = isp_2300_risc_code;
- break;
- case PCI_PRODUCT_QLOGIC_ISP2322:
- rp = isp_2322_risc_code;
- break;
-#ifdef __sparc64__
- case SBUS_PRODUCT_QLOGIC_ISP1000:
- if (tgtmode)
- break;
- rp = isp_1000_risc_code;
- break;
-#endif
- default:
- break;
- }
- }
- if (rp && addcaller(ptrp)) {
- *ptrp = rp;
- }
+#if defined(ISP_1000)
+ UMACRO(isp_1000);
+#elif defined(ISP_1040)
+ UMACRO(isp_1040);
+#elif defined(ISP_1040_IT)
+ UMACRO(isp_1040_it);
+#elif defined(ISP_1080)
+ UMACRO(isp_1080);
+#elif defined(ISP_1080_IT)
+ UMACRO(isp_1080_it);
+#elif defined(ISP_12160)
+ UMACRO(isp_12160);
+#elif defined(ISP_12160_IT)
+ UMACRO(isp_12160_it);
+#elif defined(ISP_2100)
+ UMACRO(isp_2100);
+#elif defined(ISP_2200)
+ UMACRO(isp_2200);
+#elif defined(ISP_2300)
+ UMACRO(isp_2300);
+#elif defined(ISP_2322)
+ UMACRO(isp_2322);
+#endif
+ return (0);
}
static int
-isp_module_handler(module_t mod, int what, void *arg)
+module_handler(module_t mod, int what, void *arg)
{
+ int r;
switch (what) {
case MOD_LOAD:
- isp_get_firmware_p = isp_get_firmware;
+ r = do_load_fw();
break;
case MOD_UNLOAD:
- isp_get_firmware_p = NULL;
- if (ncallers) {
- int i;
- for (i = 0; i < ncallers; i++) {
- *callp[i] = NULL;
- }
- free(callp, M_DEVBUF);
- }
+ r = do_unload_fw();
break;
default:
- return (EOPNOTSUPP);
+ r = EOPNOTSUPP;
break;
}
- return (0);
+ return (r);
}
static moduledata_t ispfw_mod = {
- "ispfw", isp_module_handler, NULL
+ MODULE_NAME, module_handler, NULL
};
-DECLARE_MODULE(ispfw, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD);
-MODULE_VERSION(ispfw, ISPFW_VERSION);
-MODULE_DEPEND(ispfw, isp, 1, 1, 1);
+#ifndef KLD_MODULE
+DECLARE_MODULE(isp, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD);
+#else
+#if defined(ISP_1000)
+DECLARE_MODULE(isp_1000, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD);
+#elif defined(ISP_1040)
+DECLARE_MODULE(isp_1040, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD);
+#elif defined(ISP_1040_IT)
+DECLARE_MODULE(isp_1040_it, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD);
+#elif defined(ISP_1080)
+DECLARE_MODULE(isp_1080, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD);
+#elif defined(ISP_1080_IT)
+DECLARE_MODULE(isp_1080_it, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD);
+#elif defined(ISP_12160)
+DECLARE_MODULE(isp_12160, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD);
+#elif defined(ISP_12160_IT)
+DECLARE_MODULE(isp_12160_IT, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD);
+#elif defined(ISP_2100)
+DECLARE_MODULE(isp_2100, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD);
+#elif defined(ISP_2200)
+DECLARE_MODULE(isp_2200, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD);
+#elif defined(ISP_2300)
+DECLARE_MODULE(isp_2300, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD);
+#elif defined(ISP_2322)
+DECLARE_MODULE(isp_2322, ispfw_mod, SI_SUB_DRIVERS, SI_ORDER_THIRD);
+#endif
+#endif
OpenPOWER on IntegriCloud