1/*- 2 * FreeBSD, EISA product support functions 3 * 4 * 5 * Copyright (c) 1994-1998, 2000, 2001 Justin T. Gibbs. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice immediately at the beginning of the file, without modification, 13 * this list of conditions, and the following disclaimer. 14 * 2. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_eisa.c#13 $ 30 */ 31 32#include <sys/cdefs.h> 33__FBSDID("$FreeBSD$"); 34 35#include <dev/aic7xxx/aic7xxx_osm.h> 36 37#include <dev/eisa/eisaconf.h> 38 39static int 40aic7770_probe(device_t dev) 41{ 42 struct aic7770_identity *entry; 43 struct resource *regs; 44 uint32_t iobase; 45 bus_space_handle_t bsh; 46 bus_space_tag_t tag; 47 u_int irq; 48 u_int intdef; 49 u_int hcntrl; 50 int shared; 51 int rid; 52 int error; 53 54 entry = aic7770_find_device(eisa_get_id(dev)); 55 if (entry == NULL) 56 return (ENXIO); 57 device_set_desc(dev, entry->name); 58 59 iobase = (eisa_get_slot(dev) * EISA_SLOT_SIZE) + AHC_EISA_SLOT_OFFSET; 60 61 eisa_add_iospace(dev, iobase, AHC_EISA_IOSIZE, RESVADDR_NONE); 62 63 rid = 0; 64 regs = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); 65 if (regs == NULL) { 66 device_printf(dev, "Unable to map I/O space?!\n"); 67 return ENOMEM; 68 } 69 70 tag = rman_get_bustag(regs); 71 bsh = rman_get_bushandle(regs); 72 error = 0; 73 74 /* Pause the card preseving the IRQ type */ 75 hcntrl = bus_space_read_1(tag, bsh, HCNTRL) & IRQMS; 76 bus_space_write_1(tag, bsh, HCNTRL, hcntrl | PAUSE); 77 while ((bus_space_read_1(tag, bsh, HCNTRL) & PAUSE) == 0) 78 ; 79 80 /* Make sure we have a valid interrupt vector */ 81 intdef = bus_space_read_1(tag, bsh, INTDEF); 82 shared = (intdef & EDGE_TRIG) ? EISA_TRIGGER_EDGE : EISA_TRIGGER_LEVEL; 83 irq = intdef & VECTOR; 84 switch (irq) { 85 case 9: 86 case 10: 87 case 11: 88 case 12: 89 case 14: 90 case 15: 91 break; 92 default: 93 printf("aic7770 at slot %d: illegal irq setting %d\n", 94 eisa_get_slot(dev), intdef); 95 error = ENXIO; 96 } 97 98 if (error == 0) 99 eisa_add_intr(dev, irq, shared); 100 101 bus_release_resource(dev, SYS_RES_IOPORT, rid, regs); 102 return (error); 103} 104 105static int 106aic7770_attach(device_t dev) 107{ 108 struct aic7770_identity *entry; 109 struct ahc_softc *ahc; 110 char *name; 111 int error; 112 113 entry = aic7770_find_device(eisa_get_id(dev)); 114 if (entry == NULL) 115 return (ENXIO); 116 117 /* 118 * Allocate a softc for this card and 119 * set it up for attachment by our 120 * common detect routine. 121 */ 122 name = malloc(strlen(device_get_nameunit(dev)) + 1, M_DEVBUF, M_NOWAIT); 123 if (name == NULL) 124 return (ENOMEM); 125 strcpy(name, device_get_nameunit(dev)); 126 ahc = ahc_alloc(dev, name); 127 if (ahc == NULL) 128 return (ENOMEM); 129 130 ahc_set_unit(ahc, device_get_unit(dev)); 131 132 /* Allocate a dmatag for our SCB DMA maps */ 133 error = aic_dma_tag_create(ahc, /*parent*/bus_get_dma_tag(dev), 134 /*alignment*/1, /*boundary*/0, 135 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 136 /*highaddr*/BUS_SPACE_MAXADDR, 137 /*filter*/NULL, /*filterarg*/NULL, 138 /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, 139 /*nsegments*/AHC_NSEG, 140 /*maxsegsz*/AHC_MAXTRANSFER_SIZE, 141 /*flags*/0, 142 &ahc->parent_dmat); 143 144 if (error != 0) { 145 printf("ahc_eisa_attach: Could not allocate DMA tag " 146 "- error %d\n", error); 147 ahc_free(ahc); 148 return (ENOMEM); 149 } 150 ahc->dev_softc = dev; 151 error = aic7770_config(ahc, entry, /*unused ioport arg*/0); 152 if (error != 0) { 153 ahc_free(ahc); 154 return (error); 155 } 156 157 ahc_attach(ahc); 158 return (0); 159} 160 161 162static device_method_t ahc_eisa_device_methods[] = { 163 /* Device interface */ 164 DEVMETHOD(device_probe, aic7770_probe), 165 DEVMETHOD(device_attach, aic7770_attach), 166 DEVMETHOD(device_detach, ahc_detach), 167 { 0, 0 } 168}; 169 170static driver_t ahc_eisa_driver = { 171 "ahc", 172 ahc_eisa_device_methods, 173 sizeof(struct ahc_softc) 174}; 175 176DRIVER_MODULE(ahc_eisa, eisa, ahc_eisa_driver, ahc_devclass, 0, 0); 177MODULE_DEPEND(ahc_eisa, ahc, 1, 1, 1); 178MODULE_VERSION(ahc_eisa, 1); 179