Deleted Added
full compact
ahc_eisa.c (119418) ahc_eisa.c (123579)
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);