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 *
| 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: ahc_eisa.c,v 1.29 2003/05/03 23:27:57 gibbs Exp $
| 29 * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_eisa.c#13 $
|
30 */ 31 32#include <sys/cdefs.h>
| 30 */ 31 32#include <sys/cdefs.h>
|
33__FBSDID("$FreeBSD: head/sys/dev/aic7xxx/ahc_eisa.c 119418 2003-08-24 17:55:58Z obrien $");
| 33__FBSDID("$FreeBSD: head/sys/dev/aic7xxx/ahc_eisa.c 123579 2003-12-17 00:02:10Z gibbs $");
|
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(dev, SYS_RES_IOPORT, &rid, 65 0, ~0, 1, RF_ACTIVE); 66 if (regs == NULL) { 67 device_printf(dev, "Unable to map I/O space?!\n"); 68 return ENOMEM; 69 } 70 71 tag = rman_get_bustag(regs); 72 bsh = rman_get_bushandle(regs); 73 error = 0; 74 75 /* Pause the card preseving the IRQ type */ 76 hcntrl = bus_space_read_1(tag, bsh, HCNTRL) & IRQMS; 77 bus_space_write_1(tag, bsh, HCNTRL, hcntrl | PAUSE); 78 while ((bus_space_read_1(tag, bsh, HCNTRL) & PAUSE) == 0) 79 ; 80 81 /* Make sure we have a valid interrupt vector */ 82 intdef = bus_space_read_1(tag, bsh, INTDEF); 83 shared = (intdef & EDGE_TRIG) ? EISA_TRIGGER_EDGE : EISA_TRIGGER_LEVEL; 84 irq = intdef & VECTOR; 85 switch (irq) { 86 case 9: 87 case 10: 88 case 11: 89 case 12: 90 case 14: 91 case 15: 92 break; 93 default: 94 printf("aic7770 at slot %d: illegal irq setting %d\n", 95 eisa_get_slot(dev), intdef); 96 error = ENXIO; 97 } 98 99 if (error == 0) 100 eisa_add_intr(dev, irq, shared); 101 102 bus_release_resource(dev, SYS_RES_IOPORT, rid, regs); 103 return (error); 104} 105 106static int 107aic7770_attach(device_t dev) 108{ 109 struct aic7770_identity *entry; 110 struct ahc_softc *ahc; 111 char *name; 112 int error; 113 114 entry = aic7770_find_device(eisa_get_id(dev)); 115 if (entry == NULL) 116 return (ENXIO); 117 118 /* 119 * Allocate a softc for this card and 120 * set it up for attachment by our 121 * common detect routine. 122 */ 123 name = malloc(strlen(device_get_nameunit(dev)) + 1, M_DEVBUF, M_NOWAIT); 124 if (name == NULL) 125 return (ENOMEM); 126 strcpy(name, device_get_nameunit(dev)); 127 ahc = ahc_alloc(dev, name); 128 if (ahc == NULL) 129 return (ENOMEM); 130 131 ahc_set_unit(ahc, device_get_unit(dev)); 132 133 /* Allocate a dmatag for our SCB DMA maps */ 134 /* XXX Should be a child of the PCI bus dma tag */
| 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(dev, SYS_RES_IOPORT, &rid, 65 0, ~0, 1, RF_ACTIVE); 66 if (regs == NULL) { 67 device_printf(dev, "Unable to map I/O space?!\n"); 68 return ENOMEM; 69 } 70 71 tag = rman_get_bustag(regs); 72 bsh = rman_get_bushandle(regs); 73 error = 0; 74 75 /* Pause the card preseving the IRQ type */ 76 hcntrl = bus_space_read_1(tag, bsh, HCNTRL) & IRQMS; 77 bus_space_write_1(tag, bsh, HCNTRL, hcntrl | PAUSE); 78 while ((bus_space_read_1(tag, bsh, HCNTRL) & PAUSE) == 0) 79 ; 80 81 /* Make sure we have a valid interrupt vector */ 82 intdef = bus_space_read_1(tag, bsh, INTDEF); 83 shared = (intdef & EDGE_TRIG) ? EISA_TRIGGER_EDGE : EISA_TRIGGER_LEVEL; 84 irq = intdef & VECTOR; 85 switch (irq) { 86 case 9: 87 case 10: 88 case 11: 89 case 12: 90 case 14: 91 case 15: 92 break; 93 default: 94 printf("aic7770 at slot %d: illegal irq setting %d\n", 95 eisa_get_slot(dev), intdef); 96 error = ENXIO; 97 } 98 99 if (error == 0) 100 eisa_add_intr(dev, irq, shared); 101 102 bus_release_resource(dev, SYS_RES_IOPORT, rid, regs); 103 return (error); 104} 105 106static int 107aic7770_attach(device_t dev) 108{ 109 struct aic7770_identity *entry; 110 struct ahc_softc *ahc; 111 char *name; 112 int error; 113 114 entry = aic7770_find_device(eisa_get_id(dev)); 115 if (entry == NULL) 116 return (ENXIO); 117 118 /* 119 * Allocate a softc for this card and 120 * set it up for attachment by our 121 * common detect routine. 122 */ 123 name = malloc(strlen(device_get_nameunit(dev)) + 1, M_DEVBUF, M_NOWAIT); 124 if (name == NULL) 125 return (ENOMEM); 126 strcpy(name, device_get_nameunit(dev)); 127 ahc = ahc_alloc(dev, name); 128 if (ahc == NULL) 129 return (ENOMEM); 130 131 ahc_set_unit(ahc, device_get_unit(dev)); 132 133 /* Allocate a dmatag for our SCB DMA maps */ 134 /* XXX Should be a child of the PCI bus dma tag */
|
135 error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/1,
| 135 error = aic_dma_tag_create(ahc, /*parent*/NULL, /*alignment*/1,
|
136 /*boundary*/0, 137 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 138 /*highaddr*/BUS_SPACE_MAXADDR, 139 /*filter*/NULL, /*filterarg*/NULL, 140 /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, 141 /*nsegments*/AHC_NSEG, 142 /*maxsegsz*/AHC_MAXTRANSFER_SIZE, 143 /*flags*/0,
| 136 /*boundary*/0, 137 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 138 /*highaddr*/BUS_SPACE_MAXADDR, 139 /*filter*/NULL, /*filterarg*/NULL, 140 /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, 141 /*nsegments*/AHC_NSEG, 142 /*maxsegsz*/AHC_MAXTRANSFER_SIZE, 143 /*flags*/0,
|
144 /*lockfunc*/busdma_lock_mutex, 145 /*lockarg*/&Giant,
| |
146 &ahc->parent_dmat); 147 148 if (error != 0) { 149 printf("ahc_eisa_attach: Could not allocate DMA tag " 150 "- error %d\n", error); 151 ahc_free(ahc); 152 return (ENOMEM); 153 } 154 ahc->dev_softc = dev; 155 error = aic7770_config(ahc, entry, /*unused ioport arg*/0); 156 if (error != 0) { 157 ahc_free(ahc); 158 return (error); 159 } 160 161 ahc_attach(ahc); 162 return (0); 163} 164 165int 166aic7770_map_registers(struct ahc_softc *ahc, u_int unused_ioport_arg) 167{ 168 struct resource *regs; 169 int rid; 170 171 rid = 0; 172 regs = bus_alloc_resource(ahc->dev_softc, SYS_RES_IOPORT, 173 &rid, 0, ~0, 1, RF_ACTIVE); 174 if (regs == NULL) { 175 device_printf(ahc->dev_softc, "Unable to map I/O space?!\n"); 176 return ENOMEM; 177 } 178 ahc->platform_data->regs_res_type = SYS_RES_IOPORT; 179 ahc->platform_data->regs_res_id = rid, 180 ahc->platform_data->regs = regs; 181 ahc->tag = rman_get_bustag(regs); 182 ahc->bsh = rman_get_bushandle(regs); 183 return (0); 184} 185 186int 187aic7770_map_int(struct ahc_softc *ahc, int irq) 188{ 189 int zero; 190 191 zero = 0; 192 ahc->platform_data->irq = 193 bus_alloc_resource(ahc->dev_softc, SYS_RES_IRQ, &zero, 194 0, ~0, 1, RF_ACTIVE); 195 if (ahc->platform_data->irq == NULL) 196 return (ENOMEM); 197 ahc->platform_data->irq_res_type = SYS_RES_IRQ; 198 return (ahc_map_int(ahc)); 199} 200 201static device_method_t ahc_eisa_device_methods[] = { 202 /* Device interface */ 203 DEVMETHOD(device_probe, aic7770_probe), 204 DEVMETHOD(device_attach, aic7770_attach), 205 DEVMETHOD(device_detach, ahc_detach), 206 { 0, 0 } 207}; 208 209static driver_t ahc_eisa_driver = { 210 "ahc", 211 ahc_eisa_device_methods, 212 sizeof(struct ahc_softc) 213}; 214 215DRIVER_MODULE(ahc_eisa, eisa, ahc_eisa_driver, ahc_devclass, 0, 0); 216MODULE_DEPEND(ahc_eisa, ahc, 1, 1, 1); 217MODULE_VERSION(ahc_eisa, 1);
| 144 &ahc->parent_dmat); 145 146 if (error != 0) { 147 printf("ahc_eisa_attach: Could not allocate DMA tag " 148 "- error %d\n", error); 149 ahc_free(ahc); 150 return (ENOMEM); 151 } 152 ahc->dev_softc = dev; 153 error = aic7770_config(ahc, entry, /*unused ioport arg*/0); 154 if (error != 0) { 155 ahc_free(ahc); 156 return (error); 157 } 158 159 ahc_attach(ahc); 160 return (0); 161} 162 163int 164aic7770_map_registers(struct ahc_softc *ahc, u_int unused_ioport_arg) 165{ 166 struct resource *regs; 167 int rid; 168 169 rid = 0; 170 regs = bus_alloc_resource(ahc->dev_softc, SYS_RES_IOPORT, 171 &rid, 0, ~0, 1, RF_ACTIVE); 172 if (regs == NULL) { 173 device_printf(ahc->dev_softc, "Unable to map I/O space?!\n"); 174 return ENOMEM; 175 } 176 ahc->platform_data->regs_res_type = SYS_RES_IOPORT; 177 ahc->platform_data->regs_res_id = rid, 178 ahc->platform_data->regs = regs; 179 ahc->tag = rman_get_bustag(regs); 180 ahc->bsh = rman_get_bushandle(regs); 181 return (0); 182} 183 184int 185aic7770_map_int(struct ahc_softc *ahc, int irq) 186{ 187 int zero; 188 189 zero = 0; 190 ahc->platform_data->irq = 191 bus_alloc_resource(ahc->dev_softc, SYS_RES_IRQ, &zero, 192 0, ~0, 1, RF_ACTIVE); 193 if (ahc->platform_data->irq == NULL) 194 return (ENOMEM); 195 ahc->platform_data->irq_res_type = SYS_RES_IRQ; 196 return (ahc_map_int(ahc)); 197} 198 199static device_method_t ahc_eisa_device_methods[] = { 200 /* Device interface */ 201 DEVMETHOD(device_probe, aic7770_probe), 202 DEVMETHOD(device_attach, aic7770_attach), 203 DEVMETHOD(device_detach, ahc_detach), 204 { 0, 0 } 205}; 206 207static driver_t ahc_eisa_driver = { 208 "ahc", 209 ahc_eisa_device_methods, 210 sizeof(struct ahc_softc) 211}; 212 213DRIVER_MODULE(ahc_eisa, eisa, ahc_eisa_driver, ahc_devclass, 0, 0); 214MODULE_DEPEND(ahc_eisa, ahc, 1, 1, 1); 215MODULE_VERSION(ahc_eisa, 1);
|