diff options
author | mdodd <mdodd@FreeBSD.org> | 2000-04-07 02:50:24 +0000 |
---|---|---|
committer | mdodd <mdodd@FreeBSD.org> | 2000-04-07 02:50:24 +0000 |
commit | bcaa5ea35b04af42346a4c1fa1b72f54e9fddb4d (patch) | |
tree | 6019f1d49bcdc9db1a0a6c726971fe5f1c33466e /sys/dev/dpt/dpt_pci.c | |
parent | e1128bd07d48d6e5290924e7436cee2c89c7bb06 (diff) | |
download | FreeBSD-src-bcaa5ea35b04af42346a4c1fa1b72f54e9fddb4d.zip FreeBSD-src-bcaa5ea35b04af42346a4c1fa1b72f54e9fddb4d.tar.gz |
- Convert dpt_pci.c to newbus.
- Add support for ISA based DPT adapters (this doesn't quite work yet).
- Sync dpt_eisa.c with my local copy.
- Simplify how EISA IDs are matched.
- Prototype.
- Formatting nits.
- Conform to how I do things in dpt_pci.c/dpt_isa.c.
- Modify dpt_scsi.c:dpt_alloc() to DTRT with newbus.
- Add some comments to dpt_scsi.c:dpt_pio_get_conf().
- Add additional check to dpt_scsi.c:dpt_get_conf().
- Add some useful error messages to dpt_scsi.c:dpt_init().
Diffstat (limited to 'sys/dev/dpt/dpt_pci.c')
-rw-r--r-- | sys/dev/dpt/dpt_pci.c | 258 |
1 files changed, 136 insertions, 122 deletions
diff --git a/sys/dev/dpt/dpt_pci.c b/sys/dev/dpt/dpt_pci.c index 884b6b6..3bb3ee6 100644 --- a/sys/dev/dpt/dpt_pci.c +++ b/sys/dev/dpt/dpt_pci.c @@ -1,24 +1,24 @@ -/* - * Copyright (c) 1997 by Simon Shapiro - * All Rights Reserved +/*- + * Copyright (c) 2000 Matthew N. Dodd <winter@jurai.net> + * All rights reserved. + * + * Copyright (c) 1997 Simon Shapiro + * 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, this list of conditions, and the following disclaimer, - * without modification, immediately at the beginning of the file. + * notice, 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 + * 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 @@ -26,161 +26,175 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * + * $FreeBSD$ */ -/* - * dptpci.c: PCI Bus Attachment for DPT SCSI HBAs - */ - -#ident "$FreeBSD$" - -#include "opt_dpt.h" - #include <sys/param.h> #include <sys/systm.h> -#include <sys/malloc.h> -#include <sys/buf.h> #include <sys/kernel.h> - -#include <pci/pcireg.h> -#include <pci/pcivar.h> +#include <sys/module.h> +#include <sys/bus.h> #include <machine/bus_memio.h> #include <machine/bus_pio.h> #include <machine/bus.h> +#include <machine/resource.h> +#include <sys/rman.h> + +#include <pci/pcireg.h> +#include <pci/pcivar.h> #include <cam/scsi/scsi_all.h> #include <dev/dpt/dpt.h> -#include <dev/dpt/dpt_pci.h> - -#define PCI_BASEADR0 PCI_MAP_REG_START /* I/O Address */ -#define PCI_BASEADR1 PCI_MAP_REG_START + 4 /* Mem I/O Address */ - -#define ISA_PRIMARY_WD_ADDRESS 0x1f8 -/* Global variables */ +#define DPT_VENDOR_ID 0x1044 +#define DPT_DEVICE_ID 0xa400 -/* Function Prototypes */ +#define DPT_PCI_IOADDR PCIR_MAPS /* I/O Address */ +#define DPT_PCI_MEMADDR (PCIR_MAPS + 4) /* Mem I/O Address */ -static const char *dpt_pci_probe(pcici_t tag, pcidi_t type); -static void dpt_pci_attach(pcici_t config_id, int unit); +#define ISA_PRIMARY_WD_ADDRESS 0x1f8 -extern struct cdevsw dpt_cdevsw; +static int dpt_pci_probe (device_t); +static int dpt_pci_attach (device_t); -static struct pci_device dpt_pci_driver = +static int +dpt_pci_probe (device_t dev) { - "dpt", - dpt_pci_probe, - dpt_pci_attach, - &dpt_unit, - NULL -}; - -COMPAT_PCI_DRIVER(dpt_pci, dpt_pci_driver); - -/* - * Probe the PCI device. - * Some of this work will have to be duplicated in _attach - * because we do not know for sure how the two relate. - */ + if ((pci_get_vendor(dev) == DPT_VENDOR_ID) && + (pci_get_device(dev) == DPT_DEVICE_ID)) { + device_set_desc(dev, "DPT Caching SCSI RAID Controller"); + return (0); + } + return (ENXIO); +} -static const char * -dpt_pci_probe(pcici_t tag, pcidi_t type) +static int +dpt_pci_attach (device_t dev) { - u_int32_t class; - -#ifndef PCI_COMMAND_MASTER_ENABLE -#define PCI_COMMAND_MASTER_ENABLE 0x00000004 + dpt_softc_t * dpt; + struct resource *io = 0; + struct resource *irq = 0; + int s; + int rid; + void * ih; + int error = 0; + + int iotype = 0; + u_int32_t command; + + command = pci_read_config(dev, PCIR_COMMAND, /*bytes*/1); + +#ifdef DPT_ALLOW_MMIO + if ((command & PCIM_CMD_MEMEN) != 0) { + rid = DPT_PCI_MEMADDR; + iotype = SYS_RES_MEMORY; + io = bus_alloc_resource(dev, iotype, &rid, 0, ~0, 1, RF_ACTIVE); + } #endif + if (io == NULL && (command & PCI_COMMAND_IO_ENABLE) != 0) { + rid = DPT_PCI_IOADDR; + iotype = SYS_RES_IOPORT; + io = bus_alloc_resource(dev, iotype, &rid, 0, ~0, 1, RF_ACTIVE); + } -#ifndef PCI_SUBCLASS_MASS_STORAGE_SCSI -#define PCI_SUBCLASS_MASS_STORAGE_SCSI 0x00000000 -#endif + if (io == NULL) { + device_printf(dev, "can't allocate register resources\n"); + error = ENOMEM; + goto bad; + } - class = pci_conf_read(tag, PCI_CLASS_REG); - if (((type & 0xffff0000) >> 16) == DPT_DEVICE_ID - && (class & PCI_CLASS_MASK) == PCI_CLASS_MASS_STORAGE - && (class & PCI_SUBCLASS_MASK) == PCI_SUBCLASS_MASS_STORAGE_SCSI) - return ("DPT Caching SCSI RAID Controller"); - return (NULL); -} + rid = 0; + irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_ACTIVE); + if (!irq) { + device_printf(dev, "No irq?!\n"); + error = ENOMEM; + goto bad; + } -static void -dpt_pci_attach(pcici_t config_id, int unit) -{ - dpt_softc_t *dpt; - vm_offset_t vaddr; -#ifdef DPT_ALLOW_MEMIO - vm_offset_t paddr; -#endif - u_int16_t io_base; - bus_space_tag_t tag; - bus_space_handle_t bsh; - u_int32_t command; - int s; - - vaddr = NULL; - command = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG); -#ifdef DPT_ALLOW_MEMIO - if ((command & PCI_COMMAND_MEM_ENABLE) == 0 - || (pci_map_mem(config_id, PCI_BASEADR1, &vaddr, &paddr)) == 0) -#endif - if ((command & PCI_COMMAND_IO_ENABLE) == 0 - || (pci_map_port(config_id, PCI_BASEADR0, &io_base)) == 0) - return; - - /* - * If the DPT is mapped as an IDE controller, - * let it be IDE controller - */ - if (io_base == ISA_PRIMARY_WD_ADDRESS - 0x10) { + /* Ensure busmastering is enabled */ + command |= PCIM_CMD_BUSMASTEREN; + pci_write_config(dev, PCIR_COMMAND, command, /*bytes*/1); + + if (rman_get_start(io) == (ISA_PRIMARY_WD_ADDRESS - 0x10)) { #ifdef DPT_DEBUG_WARN - printf("dpt%d: Mapped as an IDE controller. " - "Disabling SCSI setup\n", unit); + device_printf(dev, "Mapped as an IDE controller. " + "Disabling SCSI setup\n"); #endif - return; + error = ENXIO; + goto bad; } - /* XXX Should be passed in by parent bus */ - /* XXX Why isn't the 0x10 offset incorporated into the reg defs? */ - if (vaddr != 0) { - tag = I386_BUS_SPACE_MEM; - bsh = vaddr + 0x10; - } else { - tag = I386_BUS_SPACE_IO; - bsh = io_base + 0x10; + dpt = dpt_alloc(dev, rman_get_bustag(io), rman_get_bushandle(io)); + if (dpt == NULL) { + error = ENXIO; + goto bad; } - if ((dpt = dpt_alloc(unit, tag, bsh)) == NULL) - return; /* XXX PCI code should take return status */ - /* Allocate a dmatag representing the capabilities of this attachment */ /* XXX Should be a child of the PCI bus dma tag */ - if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/1, /*boundary*/0, - /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, - /*nsegments*/BUS_SPACE_UNRESTRICTED, - /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, - /*flags*/0, &dpt->parent_dmat) != 0) { + if (bus_dma_tag_create( /* parent */ NULL, + /* alignemnt */ 1, + /* boundary */ 0, + /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, + /* highaddr */ BUS_SPACE_MAXADDR, + /* filter */ NULL, + /* filterarg */ NULL, + /* maxsize */ BUS_SPACE_MAXSIZE_32BIT, + /* nsegments */ BUS_SPACE_UNRESTRICTED, + /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, + /* flags */ 0, + &dpt->parent_dmat) != 0) { dpt_free(dpt); - return; - } - - if (pci_map_int(config_id, dpt_intr, (void *)dpt, &cam_imask) == 0) { - dpt_free(dpt); - return; + error = ENXIO; + goto bad; } s = splcam(); + if (dpt_init(dpt) != 0) { dpt_free(dpt); - return; + error = ENXIO; + goto bad; } /* Register with the XPT */ dpt_attach(dpt); + splx(s); + + if (bus_setup_intr(dev, irq, INTR_TYPE_CAM, dpt_intr, dpt, &ih)) { + device_printf(dev, "Unable to register interrupt handler\n"); + error = ENXIO; + goto bad; + } + + return (error); + +bad: + if (io) + bus_release_resource(dev, iotype, 0, io); + if (irq) + bus_release_resource(dev, SYS_RES_IRQ, 0, irq); + + return (error); } + +static device_method_t dpt_pci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, dpt_pci_probe), + DEVMETHOD(device_attach, dpt_pci_attach), + + { 0, 0 } +}; + +static driver_t dpt_pci_driver = { + "dpt", + dpt_pci_methods, + sizeof(dpt_softc_t), +}; + +static devclass_t dpt_devclass; + +DRIVER_MODULE(dpt, pci, dpt_pci_driver, dpt_devclass, 0, 0); |