📄 isp_pci.c
字号:
/* $Id: isp_pci.c,v 1.13.2.1 1999/05/11 06:09:01 mjacob Exp $ *//* release_5_11_99 *//* * PCI specific probe and attach routines for Qlogic ISP SCSI adapters. * FreeBSD Version. * *--------------------------------------- * Copyright (c) 1997, 1998 by Matthew Jacob * NASA/Ames Research Center * All rights reserved. *--------------------------------------- * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice immediately at the beginning of the file, without modification, * this list of conditions, and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include <dev/isp/isp_freebsd.h>#include <dev/isp/asm_pci.h>#include <sys/malloc.h>#include <vm/vm.h>#include <vm/pmap.h>#include <vm/vm_extern.h>#include <pci/pcireg.h>#include <pci/pcivar.h>#if __FreeBSD_version >= 300004#include <machine/bus_memio.h>#include <machine/bus_pio.h>#include <machine/bus.h>#endif#include "opt_isp.h"static u_int16_t isp_pci_rd_reg __P((struct ispsoftc *, int));static void isp_pci_wr_reg __P((struct ispsoftc *, int, u_int16_t));#ifndef ISP_DISABLE_1080_SUPPORTstatic u_int16_t isp_pci_rd_reg_1080 __P((struct ispsoftc *, int));static void isp_pci_wr_reg_1080 __P((struct ispsoftc *, int, u_int16_t));#endifstatic int isp_pci_mbxdma __P((struct ispsoftc *));static int isp_pci_dmasetup __P((struct ispsoftc *, ISP_SCSI_XFER_T *, ispreq_t *, u_int8_t *, u_int8_t));#if __FreeBSD_version >= 300004static voidisp_pci_dmateardown __P((struct ispsoftc *, ISP_SCSI_XFER_T *, u_int32_t));#define PROBETYPE const char *#elsetypedef u_int16_t pci_port_t;#define isp_pci_dmateardown NULL#define PROBETYPE char *#endifstatic void isp_pci_reset1 __P((struct ispsoftc *));static void isp_pci_dumpregs __P((struct ispsoftc *));#ifndef ISP_DISABLE_1020_SUPPORTstatic struct ispmdvec mdvec = { isp_pci_rd_reg, isp_pci_wr_reg, isp_pci_mbxdma, isp_pci_dmasetup, isp_pci_dmateardown, NULL, isp_pci_reset1, isp_pci_dumpregs, ISP_RISC_CODE, ISP_CODE_LENGTH, ISP_CODE_ORG, ISP_CODE_VERSION, BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64, 0};#endif#ifndef ISP_DISABLE_1080_SUPPORTstatic struct ispmdvec mdvec_1080 = { isp_pci_rd_reg_1080, isp_pci_wr_reg_1080, isp_pci_mbxdma, isp_pci_dmasetup, isp_pci_dmateardown, NULL, isp_pci_reset1, isp_pci_dumpregs, ISP1080_RISC_CODE, ISP1080_CODE_LENGTH, ISP1080_CODE_ORG, ISP1080_CODE_VERSION, BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64, 0};#endif#ifndef ISP_DISABLE_2100_SUPPORTstatic struct ispmdvec mdvec_2100 = { isp_pci_rd_reg, isp_pci_wr_reg, isp_pci_mbxdma, isp_pci_dmasetup, isp_pci_dmateardown, NULL, isp_pci_reset1, isp_pci_dumpregs, ISP2100_RISC_CODE, ISP2100_CODE_LENGTH, ISP2100_CODE_ORG, ISP2100_CODE_VERSION, 0, /* Irrelevant to the 2100 */ 0};#endif#ifndef SCSI_ISP_PREFER_MEM_MAP#ifdef __alpha__#define SCSI_ISP_PREFER_MEM_MAP 0#else#define SCSI_ISP_PREFER_MEM_MAP 1#endif#endif#ifndef PCIM_CMD_INVEN#define PCIM_CMD_INVEN 0x10#endif#ifndef PCIM_CMD_BUSMASTEREN#define PCIM_CMD_BUSMASTEREN 0x0004#endif#ifndef PCIM_CMD_PERRESPEN#define PCIM_CMD_PERRESPEN 0x0040#endif#ifndef PCIM_CMD_SEREN#define PCIM_CMD_SEREN 0x0100#endif#ifndef PCIR_COMMAND#define PCIR_COMMAND 0x04#endif#ifndef PCIR_CACHELNSZ#define PCIR_CACHELNSZ 0x0c#endif#ifndef PCIR_LATTIMER#define PCIR_LATTIMER 0x0d#endif#ifndef PCIR_ROMADDR#define PCIR_ROMADDR 0x30#endif#ifndef PCI_VENDOR_QLOGIC#define PCI_VENDOR_QLOGIC 0x1077#endif#ifndef PCI_PRODUCT_QLOGIC_ISP1020#define PCI_PRODUCT_QLOGIC_ISP1020 0x1020#endif#ifndef PCI_PRODUCT_QLOGIC_ISP1080#define PCI_PRODUCT_QLOGIC_ISP1080 0x1080#endif#ifndef PCI_PRODUCT_QLOGIC_ISP1240#define PCI_PRODUCT_QLOGIC_ISP1240 0x1240#endif#ifndef PCI_PRODUCT_QLOGIC_ISP2100#define PCI_PRODUCT_QLOGIC_ISP2100 0x2100#endif#define PCI_QLOGIC_ISP ((PCI_PRODUCT_QLOGIC_ISP1020 << 16) | PCI_VENDOR_QLOGIC)#define PCI_QLOGIC_ISP1080 \ ((PCI_PRODUCT_QLOGIC_ISP1080 << 16) | PCI_VENDOR_QLOGIC)#define PCI_QLOGIC_ISP1240 \ ((PCI_PRODUCT_QLOGIC_ISP1240 << 16) | PCI_VENDOR_QLOGIC)#define PCI_QLOGIC_ISP2100 \ ((PCI_PRODUCT_QLOGIC_ISP2100 << 16) | PCI_VENDOR_QLOGIC)#define IO_MAP_REG 0x10#define MEM_MAP_REG 0x14#define PCI_DFLT_LTNCY 0x40#define PCI_DFLT_LNSZ 0x10static PROBETYPE isp_pci_probe __P((pcici_t tag, pcidi_t type));static void isp_pci_attach __P((pcici_t config_d, int unit));/* This distinguishing define is not right, but it does work */ #if __FreeBSD_version < 300004#define IO_SPACE_MAPPING 0#define MEM_SPACE_MAPPING 1typedef int bus_space_tag_t;typedef u_long bus_space_handle_t;typedef unsigned int __uintptr_t;typedef __uintptr_t uintptr_t;#ifdef __alpha__#define bus_space_read_2(st, sh, offset) \ alpha_mb(), (st == IO_SPACE_MAPPING)? \ inw((pci_port_t)sh + offset) : readw((pci_port_t)sh + offset)#define bus_space_write_2(st, sh, offset, val) \ ((st == IO_SPACE_MAPPING)? outw((pci_port_t)sh + offset, val) : \ writew((pci_port_t)sh + offset, val)), alpha_mb()#else#define bus_space_read_2(st, sh, offset) \ (st == IO_SPACE_MAPPING)? \ inw((pci_port_t)sh + offset) : *((u_int16_t *)(uintptr_t)sh)#define bus_space_write_2(st, sh, offset, val) \ if (st == IO_SPACE_MAPPING) outw((pci_port_t)sh + offset, val); else \ *((u_int16_t *)(uintptr_t)sh) = val#endif#else#ifdef __alpha__#define IO_SPACE_MAPPING ALPHA_BUS_SPACE_IO#define MEM_SPACE_MAPPING ALPHA_BUS_SPACE_MEM#else#define IO_SPACE_MAPPING I386_BUS_SPACE_IO#define MEM_SPACE_MAPPING I386_BUS_SPACE_MEM#endif#endifstruct isp_pcisoftc { struct ispsoftc pci_isp; pcici_t pci_id; bus_space_tag_t pci_st; bus_space_handle_t pci_sh; int16_t pci_poff[_NREG_BLKS];#if __FreeBSD_version >= 300004 bus_dma_tag_t parent_dmat; bus_dma_tag_t cntrol_dmat; bus_dmamap_t cntrol_dmap; bus_dmamap_t dmaps[MAXISPREQUEST];#endif};static u_long ispunit;struct pci_device isp_pci_driver = { "isp", isp_pci_probe, isp_pci_attach, &ispunit, NULL};DATA_SET (pcidevice_set, isp_pci_driver);static PROBETYPEisp_pci_probe(pcici_t tag, pcidi_t type){ static int oneshot = 1; char *x; switch (type) {#ifndef ISP_DISABLE_1020_SUPPORT case PCI_QLOGIC_ISP: x = "Qlogic ISP 1020/1040 PCI SCSI Adapter"; break;#endif#ifndef ISP_DISABLE_1080_SUPPORT case PCI_QLOGIC_ISP1080: x = "Qlogic ISP 1080 PCI SCSI Adapter"; break; case PCI_QLOGIC_ISP1240: x = "Qlogic ISP 1240 PCI SCSI Adapter"; break;#endif#ifndef ISP_DISABLE_2100_SUPPORT case PCI_QLOGIC_ISP2100: x = "Qlogic ISP 2100 PCI FC-AL Adapter"; break;#endif default: return (NULL); } if (oneshot) { oneshot = 0; printf("%s Version %d.%d, Core Version %d.%d\n", PVS, ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR, ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR); } return (x);}static voidisp_pci_attach(pcici_t config_id, int unit){ int mapped; pci_port_t io_port; u_int32_t data, linesz, psize, basetype; struct isp_pcisoftc *pcs; struct ispsoftc *isp; vm_offset_t vaddr, paddr; struct ispmdvec *mdvp; ISP_LOCKVAL_DECL; pcs = malloc(sizeof (struct isp_pcisoftc), M_DEVBUF, M_NOWAIT); if (pcs == NULL) { printf("isp%d: cannot allocate softc\n", unit); return; } bzero(pcs, sizeof (struct isp_pcisoftc)); vaddr = paddr = NULL; mapped = 0; linesz = PCI_DFLT_LNSZ; /* * Note that pci_conf_read is a 32 bit word aligned function. */ data = pci_conf_read(config_id, PCIR_COMMAND);#if SCSI_ISP_PREFER_MEM_MAP == 1 if (mapped == 0 && (data & PCI_COMMAND_MEM_ENABLE)) { if (pci_map_mem(config_id, MEM_MAP_REG, &vaddr, &paddr)) { pcs->pci_st = MEM_SPACE_MAPPING; pcs->pci_sh = vaddr; mapped++; } } if (mapped == 0 && (data & PCI_COMMAND_IO_ENABLE)) { if (pci_map_port(config_id, PCI_MAP_REG_START, &io_port)) { pcs->pci_st = IO_SPACE_MAPPING; pcs->pci_sh = io_port; mapped++; } }#else if (mapped == 0 && (data & PCI_COMMAND_IO_ENABLE)) { if (pci_map_port(config_id, PCI_MAP_REG_START, &io_port)) { pcs->pci_st = IO_SPACE_MAPPING; pcs->pci_sh = io_port; mapped++; } } if (mapped == 0 && (data & PCI_COMMAND_MEM_ENABLE)) { if (pci_map_mem(config_id, MEM_MAP_REG, &vaddr, &paddr)) { pcs->pci_st = MEM_SPACE_MAPPING; pcs->pci_sh = vaddr; mapped++; } }#endif if (mapped == 0) { printf("isp%d: unable to map any ports!\n", unit); free(pcs, M_DEVBUF); return; } printf("isp%d: using %s space register mapping\n", unit, pcs->pci_st == IO_SPACE_MAPPING? "I/O" : "Memory"); data = pci_conf_read(config_id, PCI_ID_REG); pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF; pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF; pcs->pci_poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF; pcs->pci_poff[RISC_BLOCK >> _BLK_REG_SHFT] = PCI_RISC_REGS_OFF; pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF; /* * GCC! */ mdvp = &mdvec; basetype = ISP_HA_SCSI_UNKNOWN; psize = sizeof (sdparam);#ifndef ISP_DISABLE_1020_SUPPORT if (data == PCI_QLOGIC_ISP) { mdvp = &mdvec; basetype = ISP_HA_SCSI_UNKNOWN; psize = sizeof (sdparam); }#endif#ifndef ISP_DISABLE_1080_SUPPORT if (data == PCI_QLOGIC_ISP1080) { mdvp = &mdvec_1080; basetype = ISP_HA_SCSI_1080; psize = sizeof (sdparam); pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = ISP1080_DMA_REGS_OFF;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -