ahc_eisa.c revision 161928
19213Swollman/*- 250479Speter * FreeBSD, EISA product support functions 31553Srgrimes * 4156813Sru * 5156813Sru * Copyright (c) 1994-1998, 2000, 2001 Justin T. Gibbs. 6223209Sed * All rights reserved. 738658Sgpalmer * 8266272Ssbruno * Redistribution and use in source and binary forms, with or without 9252862Sdteske * modification, are permitted provided that the following conditions 10292348Sken * are met: 1138658Sgpalmer * 1. Redistributions of source code must retain the above copyright 1238658Sgpalmer * notice immediately at the beginning of the file, without modification, 1338658Sgpalmer * this list of conditions, and the following disclaimer. 1438658Sgpalmer * 2. The name of the author may not be used to endorse or promote products 1538658Sgpalmer * derived from this software without specific prior written permission. 16177633Sdfr * 17181335Sjhb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1838658Sgpalmer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19229997Sken * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20255570Strasz * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 2182547Smike * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22121468Ssimokawa * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23295131Sjhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2475753Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2576195Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26113287Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27185032Simp * SUCH DAMAGE. 28102858Sphk * 2959247Srwatson * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_eisa.c#13 $ 30177027Sphk */ 31277434Strasz 32108441Ssimokawa#include <sys/cdefs.h> 33105756Srwatson__FBSDID("$FreeBSD: head/sys/dev/aic7xxx/ahc_eisa.c 161928 2006-09-03 00:27:42Z jmg $"); 34105756Srwatson 35112444Sphk#include <dev/aic7xxx/aic7xxx_osm.h> 36187712Sraj 3755210Sshin#include <dev/eisa/eisaconf.h> 3841043Sdima 3983322Speterstatic int 4081878Speteraic7770_probe(device_t dev) 41186344Ssam{ 4245412Smsmith struct aic7770_identity *entry; 4352403Sbillf struct resource *regs; 44196200Sscottl uint32_t iobase; 4553127Sdfr bus_space_handle_t bsh; 4659141Smsmith bus_space_tag_t tag; 47124587Sru u_int irq; 48294364Sian u_int intdef; 49196212Sscottl u_int hcntrl; 5038658Sgpalmer int shared; 51262650Sbrooks int rid; 5238658Sgpalmer int error; 53192811Srmacklem 5499549Sgordon entry = aic7770_find_device(eisa_get_id(dev)); 55192811Srmacklem if (entry == NULL) 56192811Srmacklem return (ENXIO); 57192811Srmacklem device_set_desc(dev, entry->name); 58244562Sbrooks 59126917Scperciva iobase = (eisa_get_slot(dev) * EISA_SLOT_SIZE) + AHC_EISA_SLOT_OFFSET; 60245606Seadler 6138658Sgpalmer eisa_add_iospace(dev, iobase, AHC_EISA_IOSIZE, RESVADDR_NONE); 6238658Sgpalmer 63142578Snjl rid = 0; 6438658Sgpalmer regs = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); 6538658Sgpalmer if (regs == NULL) { 6638658Sgpalmer device_printf(dev, "Unable to map I/O space?!\n"); 6738658Sgpalmer return ENOMEM; 6838658Sgpalmer } 6938658Sgpalmer 7038658Sgpalmer tag = rman_get_bustag(regs); 7174462Salfred bsh = rman_get_bushandle(regs); 7238658Sgpalmer error = 0; 7338658Sgpalmer 7453494Sdillon /* Pause the card preseving the IRQ type */ 7541043Sdima hcntrl = bus_space_read_1(tag, bsh, HCNTRL) & IRQMS; 76200743Sdougb bus_space_write_1(tag, bsh, HCNTRL, hcntrl | PAUSE); 77206156Sume while ((bus_space_read_1(tag, bsh, HCNTRL) & PAUSE) == 0) 78289290Sbapt ; 79178895Sjulian 80105756Srwatson /* Make sure we have a valid interrupt vector */ 81105756Srwatson intdef = bus_space_read_1(tag, bsh, INTDEF); 82129333Sjoerg shared = (intdef & EDGE_TRIG) ? EISA_TRIGGER_EDGE : EISA_TRIGGER_LEVEL; 83148215Smarks irq = intdef & VECTOR; 8438658Sgpalmer switch (irq) { 8538658Sgpalmer case 9: 86252862Sdteske case 10: 87141381Smaxim case 11: 8838658Sgpalmer case 12: 8938658Sgpalmer case 14: 9038658Sgpalmer case 15: 9138658Sgpalmer break; 92282974Strasz default: 93101209Srwatson printf("aic7770 at slot %d: illegal irq setting %d\n", 94294787Sdes eisa_get_slot(dev), intdef); 9538658Sgpalmer error = ENXIO; 96195200Smbr } 9738658Sgpalmer 98116874Ssmkelly if (error == 0) 99212525Simp eisa_add_intr(dev, irq, shared); 1001553Srgrimes 101183242Ssam bus_release_resource(dev, SYS_RES_IOPORT, rid, regs); 102183242Ssam return (error); 103183242Ssam} 104212525Simp 105212525Simpstatic int 106124587Sruaic7770_attach(device_t dev) 107124587Sru{ 108183242Ssam struct aic7770_identity *entry; 109212525Simp struct ahc_softc *ahc; 110183242Ssam char *name; 111183242Ssam int error; 112156813Sru 113212525Simp entry = aic7770_find_device(eisa_get_id(dev)); 114212525Simp if (entry == NULL) 115243752Srwatson return (ENXIO); 116243752Srwatson 117243752Srwatson /* 118212525Simp * Allocate a softc for this card and 119212525Simp * set it up for attachment by our 120155815Srwatson * common detect routine. 121155815Srwatson */ 122183242Ssam name = malloc(strlen(device_get_nameunit(dev)) + 1, M_DEVBUF, M_NOWAIT); 123212525Simp if (name == NULL) 124183242Ssam return (ENOMEM); 125183242Ssam strcpy(name, device_get_nameunit(dev)); 126278558Sngie ahc = ahc_alloc(dev, name); 127278558Sngie if (ahc == NULL) 128278558Sngie return (ENOMEM); 129278558Sngie 130156813Sru ahc_set_unit(ahc, device_get_unit(dev)); 131212525Simp 132131768Semax /* Allocate a dmatag for our SCB DMA maps */ 133131768Semax /* XXX Should be a child of the PCI bus dma tag */ 134279505Sngie error = aic_dma_tag_create(ahc, /*parent*/bus_get_dma_tag(dev), 135279505Sngie /*alignment*/1, /*boundary*/0, 136279505Sngie /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 137279505Sngie /*highaddr*/BUS_SPACE_MAXADDR, 138278713Sngie /*filter*/NULL, /*filterarg*/NULL, 139278713Sngie /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, 140278713Sngie /*nsegments*/AHC_NSEG, 141278713Sngie /*maxsegsz*/AHC_MAXTRANSFER_SIZE, 142183242Ssam /*flags*/0, 143212525Simp &ahc->parent_dmat); 144124587Sru 145124587Sru if (error != 0) { 146183242Ssam printf("ahc_eisa_attach: Could not allocate DMA tag " 147212525Simp "- error %d\n", error); 148171173Smlaier ahc_free(ahc); 149171173Smlaier return (ENOMEM); 150183242Ssam } 151212525Simp ahc->dev_softc = dev; 152212525Simp error = aic7770_config(ahc, entry, /*unused ioport arg*/0); 153212525Simp if (error != 0) { 154212525Simp ahc_free(ahc); 155183242Ssam return (error); 156183242Ssam } 157262650Sbrooks 158262650Sbrooks ahc_attach(ahc); 159262650Sbrooks return (0); 160262650Sbrooks} 161183242Ssam 162212525Simp 163183242Ssamstatic device_method_t ahc_eisa_device_methods[] = { 164183242Ssam /* Device interface */ 165214885Suqs DEVMETHOD(device_probe, aic7770_probe), 166212525Simp DEVMETHOD(device_attach, aic7770_attach), 167184588Sdfr DEVMETHOD(device_detach, ahc_detach), 168184588Sdfr { 0, 0 } 169213462Sgonzo}; 170213462Sgonzo 171213462Sgonzostatic driver_t ahc_eisa_driver = { 172213462Sgonzo "ahc", 173156813Sru ahc_eisa_device_methods, 174212525Simp sizeof(struct ahc_softc) 175212525Simp}; 176212525Simp 177212525SimpDRIVER_MODULE(ahc_eisa, eisa, ahc_eisa_driver, ahc_devclass, 0, 0); 178212525SimpMODULE_DEPEND(ahc_eisa, ahc, 1, 1, 1); 179212525SimpMODULE_VERSION(ahc_eisa, 1); 180212525Simp