diff options
author | mjacob <mjacob@FreeBSD.org> | 2006-07-09 17:50:20 +0000 |
---|---|---|
committer | mjacob <mjacob@FreeBSD.org> | 2006-07-09 17:50:20 +0000 |
commit | a6dea567ad2965b9db76644f687e9f9e987be2ff (patch) | |
tree | 02927e03d3704d09891594870139269cd8f3c287 /sys/dev/isp/isp_pci.c | |
parent | 685013634879c9cf1799d85237fd981587e51745 (diff) | |
download | FreeBSD-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/isp/isp_pci.c')
-rw-r--r-- | sys/dev/isp/isp_pci.c | 79 |
1 files changed, 76 insertions, 3 deletions
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c index 1186cce..f094d09 100644 --- a/sys/dev/isp/isp_pci.c +++ b/sys/dev/isp/isp_pci.c @@ -35,9 +35,12 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <sys/kernel.h> #include <sys/module.h> +#if __FreeBSD_version >= 700000 +#include <sys/linker.h> +#include <sys/firmware.h> +#endif #include <sys/bus.h> #if __FreeBSD_version < 500000 -#include <sys/bus.h> #include <pci/pcireg.h> #include <pci/pcivar.h> #include <machine/bus_memio.h> @@ -72,6 +75,7 @@ isp_pci_dmasetup(ispsoftc_t *, XS_T *, ispreq_t *, uint16_t *, uint16_t); static void isp_pci_dmateardown(ispsoftc_t *, XS_T *, uint16_t); + static void isp_pci_reset1(ispsoftc_t *); static void isp_pci_dumpregs(ispsoftc_t *, const char *); @@ -241,6 +245,11 @@ static struct ispmdvec mdvec_2300 = { #define PCI_PRODUCT_QLOGIC_ISP6312 0x6312 #endif +#ifndef PCI_PRODUCT_QLOGIC_ISP6322 +#define PCI_PRODUCT_QLOGIC_ISP6322 0x6322 +#endif + + #define PCI_QLOGIC_ISP1020 \ ((PCI_PRODUCT_QLOGIC_ISP1020 << 16) | PCI_VENDOR_QLOGIC) @@ -280,6 +289,9 @@ static struct ispmdvec mdvec_2300 = { #define PCI_QLOGIC_ISP6312 \ ((PCI_PRODUCT_QLOGIC_ISP6312 << 16) | PCI_VENDOR_QLOGIC) +#define PCI_QLOGIC_ISP6322 \ + ((PCI_PRODUCT_QLOGIC_ISP6322 << 16) | PCI_VENDOR_QLOGIC) + /* * Odd case for some AMI raid cards... We need to *not* attach to this. */ @@ -306,7 +318,6 @@ struct isp_pcisoftc { bus_dma_tag_t dmat; bus_dmamap_t *dmaps; }; -extern ispfwfunc *isp_get_firmware_p; static device_method_t isp_pci_methods[] = { /* Device interface */ @@ -321,6 +332,13 @@ static driver_t isp_pci_driver = { }; static devclass_t isp_devclass; DRIVER_MODULE(isp, pci, isp_pci_driver, isp_devclass, 0, 0); +#if __FreeBSD_version >= 700000 +MODULE_DEPEND(isp, ispfw, 1, 1, 1); +MODULE_DEPEND(isp, firmware, 1, 1, 1); +#else +typedef void ispfwfunc(int, int, int, uint16_t **); +extern ispfwfunc *isp_get_firmware_p; +#endif static int isp_pci_probe(device_t dev) @@ -368,6 +386,9 @@ isp_pci_probe(device_t dev) case PCI_QLOGIC_ISP6312: device_set_desc(dev, "Qlogic ISP 6312 PCI FC-AL Adapter"); break; + case PCI_QLOGIC_ISP6322: + device_set_desc(dev, "Qlogic ISP 6322 PCI FC-AL Adapter"); + break; default: return (ENXIO); } @@ -848,7 +869,8 @@ isp_pci_attach(device_t dev) pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2300_OFF; } - if (pci_get_devid(dev) == PCI_QLOGIC_ISP2322) { + if (pci_get_devid(dev) == PCI_QLOGIC_ISP2322 || + pci_get_devid(dev) == PCI_QLOGIC_ISP6322) { mdvp = &mdvec_2300; basetype = ISP_HA_FC_2322; psize = sizeof (fcparam); @@ -873,10 +895,58 @@ isp_pci_attach(device_t dev) isp->isp_revision = pci_get_revid(dev); isp->isp_dev = dev; +#if __FreeBSD_version >= 700000 /* * Try and find firmware for this device. */ + { + char fwname[32]; + unsigned int did = pci_get_device(dev); + /* + * Map a few pci ids to fw names + */ + switch (did) { + case PCI_PRODUCT_QLOGIC_ISP1020: + did = 0x1040; + break; + case PCI_PRODUCT_QLOGIC_ISP1240: + did = 0x1080; + break; + case PCI_PRODUCT_QLOGIC_ISP10160: + case PCI_PRODUCT_QLOGIC_ISP12160: + did = 0x12160; + break; + case PCI_PRODUCT_QLOGIC_ISP6312: + case PCI_PRODUCT_QLOGIC_ISP2312: + did = 0x2300; + break; + case PCI_PRODUCT_QLOGIC_ISP6322: + did = 0x2322; + break; + default: + break; + } + + isp->isp_osinfo.fw = NULL; + if (isp->isp_role & ISP_ROLE_TARGET) { + snprintf(fwname, sizeof (fwname), "isp_%04x_it", did); + isp->isp_osinfo.fw = firmware_get(fwname); + } + if (isp->isp_osinfo.fw == NULL) { + snprintf(fwname, sizeof (fwname), "isp_%04x", did); + isp->isp_osinfo.fw = firmware_get(fwname); + } + if (isp->isp_osinfo.fw != NULL) { + union { + const void *fred; + uint16_t *bob; + } u; + u.fred = isp->isp_osinfo.fw->data; + isp->isp_mdvec->dv_ispfw = u.bob; + } + } +#else if (isp_get_firmware_p) { int device = (int) pci_get_device(dev); #ifdef ISP_TARGET_MODE @@ -885,6 +955,7 @@ isp_pci_attach(device_t dev) (*isp_get_firmware_p)(0, 0, device, &mdvp->dv_ispfw); #endif } +#endif /* * Make sure that SERR, PERR, WRITE INVALIDATE and BUSMASTER @@ -892,9 +963,11 @@ isp_pci_attach(device_t dev) */ cmd |= PCIM_CMD_SEREN | PCIM_CMD_PERRESPEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_INVEN; + if (IS_2300(isp)) { /* per QLogic errata */ cmd &= ~PCIM_CMD_INVEN; } + if (IS_23XX(isp)) { /* * Can't tell if ROM will hang on 'ABOUT FIRMWARE' command. |