Deleted Added
full compact
aha_isa.c (39616) aha_isa.c (40160)
1/*
2 * Product specific probe and attach routines for:
3 * Adaptec 154x.
4 *
5 * Derived from code written by:
6 *
7 * Copyright (c) 1998 Justin T. Gibbs
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions, and the following disclaimer,
15 * without modification, immediately at the beginning of the file.
16 * 2. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
1/*
2 * Product specific probe and attach routines for:
3 * Adaptec 154x.
4 *
5 * Derived from code written by:
6 *
7 * Copyright (c) 1998 Justin T. Gibbs
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions, and the following disclaimer,
15 * without modification, immediately at the beginning of the file.
16 * 2. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * $Id: aha_isa.c,v 1.1 1998/09/15 07:39:55 gibbs Exp $
31 * $Id: aha_isa.c,v 1.2 1998/09/24 10:43:42 bde Exp $
32 */
33
34#include <sys/param.h>
35#include <sys/systm.h>
36
37#include <machine/bus_pio.h>
38#include <machine/bus.h>
39
40#include <i386/isa/isa_device.h>
41#include <dev/aha/ahareg.h>
42
43#include <cam/scsi/scsi_all.h>
44
45static int aha_isa_probe __P((struct isa_device *dev));
46static int aha_isa_attach __P((struct isa_device *dev));
47static void aha_isa_intr __P((void *unit));
48
49struct isa_driver ahadriver =
50{
51 aha_isa_probe,
52 aha_isa_attach,
53 "aha"
54};
55
56/*
57 * Check if the device can be found at the port given
58 * and if so, set it up ready for further work
59 * as an argument, takes the isa_device structure from
60 * autoconf.c
61 */
62static int
63aha_isa_probe(dev)
64 struct isa_device *dev;
65{
66 /*
67 * find unit and check we have that many defined
68 */
69 struct aha_softc *aha;
70 int port_index;
71 int max_port_index;
72
73 /*
74 * We ignore the unit number assigned by config to allow
75 * consistant numbering between PCI/EISA/ISA devices.
76 * This is a total kludge until we have a configuration
77 * manager.
78 */
79 dev->id_unit = aha_unit;
80
81 aha = NULL;
82 port_index = 0;
83 max_port_index = AHA_NUM_ISAPORTS - 1;
84 /*
85 * Bound our board search if the user has
86 * specified an exact port.
87 */
88 if (dev->id_iobase > 0) {
89 for (;port_index <= max_port_index; port_index++)
90 if (dev->id_iobase >= aha_isa_ports[port_index].addr)
91 break;
92 if ((port_index > max_port_index)
93 || (dev->id_iobase != aha_isa_ports[port_index].addr)) {
94 printf("
95aha_isa_probe: Invalid baseport of 0x%x specified.
96aha_isa_probe: Nearest valid baseport is 0x%x.
97aha_isa_probe: Failing probe.\n",
98 dev->id_iobase,
99 (port_index <= max_port_index)
100 ? aha_isa_ports[port_index].addr
101 : aha_isa_ports[max_port_index].addr);
102 return 0;
103 }
32 */
33
34#include <sys/param.h>
35#include <sys/systm.h>
36
37#include <machine/bus_pio.h>
38#include <machine/bus.h>
39
40#include <i386/isa/isa_device.h>
41#include <dev/aha/ahareg.h>
42
43#include <cam/scsi/scsi_all.h>
44
45static int aha_isa_probe __P((struct isa_device *dev));
46static int aha_isa_attach __P((struct isa_device *dev));
47static void aha_isa_intr __P((void *unit));
48
49struct isa_driver ahadriver =
50{
51 aha_isa_probe,
52 aha_isa_attach,
53 "aha"
54};
55
56/*
57 * Check if the device can be found at the port given
58 * and if so, set it up ready for further work
59 * as an argument, takes the isa_device structure from
60 * autoconf.c
61 */
62static int
63aha_isa_probe(dev)
64 struct isa_device *dev;
65{
66 /*
67 * find unit and check we have that many defined
68 */
69 struct aha_softc *aha;
70 int port_index;
71 int max_port_index;
72
73 /*
74 * We ignore the unit number assigned by config to allow
75 * consistant numbering between PCI/EISA/ISA devices.
76 * This is a total kludge until we have a configuration
77 * manager.
78 */
79 dev->id_unit = aha_unit;
80
81 aha = NULL;
82 port_index = 0;
83 max_port_index = AHA_NUM_ISAPORTS - 1;
84 /*
85 * Bound our board search if the user has
86 * specified an exact port.
87 */
88 if (dev->id_iobase > 0) {
89 for (;port_index <= max_port_index; port_index++)
90 if (dev->id_iobase >= aha_isa_ports[port_index].addr)
91 break;
92 if ((port_index > max_port_index)
93 || (dev->id_iobase != aha_isa_ports[port_index].addr)) {
94 printf("
95aha_isa_probe: Invalid baseport of 0x%x specified.
96aha_isa_probe: Nearest valid baseport is 0x%x.
97aha_isa_probe: Failing probe.\n",
98 dev->id_iobase,
99 (port_index <= max_port_index)
100 ? aha_isa_ports[port_index].addr
101 : aha_isa_ports[max_port_index].addr);
102 return 0;
103 }
104 max_port_index = port_index;
104 }
105
106 /* Attempt to find an adapter */
107 for (;port_index <= max_port_index; port_index++) {
108 config_data_t config_data;
109 u_int ioport;
110 int error;
111
112 ioport = aha_isa_ports[port_index].addr;
113
114 /*
115 * Ensure this port has not already been claimed already
116 * by a PCI or EISA adapter.
117 */
118 if (aha_check_probed_iop(ioport) != 0)
119 continue;
120
105 }
106
107 /* Attempt to find an adapter */
108 for (;port_index <= max_port_index; port_index++) {
109 config_data_t config_data;
110 u_int ioport;
111 int error;
112
113 ioport = aha_isa_ports[port_index].addr;
114
115 /*
116 * Ensure this port has not already been claimed already
117 * by a PCI or EISA adapter.
118 */
119 if (aha_check_probed_iop(ioport) != 0)
120 continue;
121
122 /*
123 * Make sure that we do not conflict with another device's
124 * I/O address.
125 */
126 if (haveseen_isadev(dev, CC_IOADDR))
127 continue;
128
121 /* Allocate a softc for use during probing */
122 aha = aha_alloc(dev->id_unit, I386_BUS_SPACE_IO, ioport);
123
124 if (aha == NULL)
125 break;
126
127 /* We're going to attempt to probe it now, so mark it probed */
128 aha_mark_probed_bio(port_index);
129
130 /* See if there is really a card present */
131 if (aha_probe(aha) || aha_fetch_adapter_info(aha)) {
132 aha_free(aha);
133 continue;
134 }
135
136 /*
137 * Determine our IRQ, and DMA settings and
138 * export them to the configuration system.
139 */
140 error = aha_cmd(aha, BOP_INQUIRE_CONFIG, NULL, /*parmlen*/0,
141 (u_int8_t*)&config_data, sizeof(config_data),
142 DEFAULT_CMD_TIMEOUT);
143 if (error != 0) {
144 printf("aha_isa_probe: Could not determine IRQ or DMA "
145 "settings for adapter at 0x%x. Failing probe\n",
146 ioport);
147 aha_free(aha);
148 continue;
149 }
150
151 switch (config_data.dma_chan) {
152 case DMA_CHAN_5:
153 dev->id_drq = 5;
154 break;
155 case DMA_CHAN_6:
156 dev->id_drq = 6;
157 break;
158 case DMA_CHAN_7:
159 dev->id_drq = 7;
160 break;
161 default:
162 printf("aha_isa_probe: Invalid DMA setting "
163 "detected for adapter at 0x%x. "
164 "Failing probe\n", ioport);
165 }
166 dev->id_iobase = aha_isa_ports[port_index].addr;
167 dev->id_irq = (config_data.irq << 9);
168 dev->id_intr = aha_isa_intr;
129 /* Allocate a softc for use during probing */
130 aha = aha_alloc(dev->id_unit, I386_BUS_SPACE_IO, ioport);
131
132 if (aha == NULL)
133 break;
134
135 /* We're going to attempt to probe it now, so mark it probed */
136 aha_mark_probed_bio(port_index);
137
138 /* See if there is really a card present */
139 if (aha_probe(aha) || aha_fetch_adapter_info(aha)) {
140 aha_free(aha);
141 continue;
142 }
143
144 /*
145 * Determine our IRQ, and DMA settings and
146 * export them to the configuration system.
147 */
148 error = aha_cmd(aha, BOP_INQUIRE_CONFIG, NULL, /*parmlen*/0,
149 (u_int8_t*)&config_data, sizeof(config_data),
150 DEFAULT_CMD_TIMEOUT);
151 if (error != 0) {
152 printf("aha_isa_probe: Could not determine IRQ or DMA "
153 "settings for adapter at 0x%x. Failing probe\n",
154 ioport);
155 aha_free(aha);
156 continue;
157 }
158
159 switch (config_data.dma_chan) {
160 case DMA_CHAN_5:
161 dev->id_drq = 5;
162 break;
163 case DMA_CHAN_6:
164 dev->id_drq = 6;
165 break;
166 case DMA_CHAN_7:
167 dev->id_drq = 7;
168 break;
169 default:
170 printf("aha_isa_probe: Invalid DMA setting "
171 "detected for adapter at 0x%x. "
172 "Failing probe\n", ioport);
173 }
174 dev->id_iobase = aha_isa_ports[port_index].addr;
175 dev->id_irq = (config_data.irq << 9);
176 dev->id_intr = aha_isa_intr;
177
178 /*
179 * OK, check to make sure that we're not stepping on
180 * someone else's IRQ or DRQ
181 */
182 if (haveseen_isadev(dev, CC_DRQ)) {
183 printf("aha_isa_probe: Aha card at I/O 0x%x's drq %d "
184 "conflicts, ignoring card.\n", dev->id_iobase,
185 dev->id_drq);
186 aha_free(aha);
187 return 0;
188 }
189 if (haveseen_isadev(dev, CC_IRQ)) {
190 printf("aha_isa_probe: Aha card at I/O 0x%x's irq %d "
191 "conflicts, ignoring card.\n", dev->id_iobase,
192 config_data.irq + 9);
193 aha_free(aha);
194 return 0;
195 }
169 aha_unit++;
170 return (AHA_NREGS);
171 }
172
173 return (0);
174}
175
176/*
177 * Attach all the sub-devices we can find
178 */
179static int
180aha_isa_attach(dev)
181 struct isa_device *dev;
182{
183 struct aha_softc *aha;
184 bus_dma_filter_t *filter;
185 void *filter_arg;
186 bus_addr_t lowaddr;
187
188 aha = aha_softcs[dev->id_unit];
189 if (dev->id_drq != -1)
190 isa_dmacascade(dev->id_drq);
191
192 /* Allocate our parent dmatag */
193 filter = NULL;
194 filter_arg = NULL;
195 lowaddr = BUS_SPACE_MAXADDR_24BIT;
196
197 if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/0, /*boundary*/0,
198 lowaddr, /*highaddr*/BUS_SPACE_MAXADDR,
199 filter, filter_arg,
200 /*maxsize*/BUS_SPACE_MAXSIZE_24BIT,
201 /*nsegments*/BUS_SPACE_UNRESTRICTED,
202 /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT,
203 /*flags*/0, &aha->parent_dmat) != 0) {
204 aha_free(aha);
205 return (-1);
206 }
207
208 if (aha_init(aha)) {
209 printf("aha init failed\n");
210 aha_free(aha);
211 return (-1);
212 }
213
214 return (aha_attach(aha));
215}
216
217/*
218 * Handle an ISA interrupt.
219 * XXX should go away as soon as ISA interrupt handlers
220 * take a (void *) arg.
221 */
222static void
223aha_isa_intr(void *unit)
224{
225 struct aha_softc* arg = aha_softcs[(int)unit];
226 aha_intr((void *)arg);
227}
196 aha_unit++;
197 return (AHA_NREGS);
198 }
199
200 return (0);
201}
202
203/*
204 * Attach all the sub-devices we can find
205 */
206static int
207aha_isa_attach(dev)
208 struct isa_device *dev;
209{
210 struct aha_softc *aha;
211 bus_dma_filter_t *filter;
212 void *filter_arg;
213 bus_addr_t lowaddr;
214
215 aha = aha_softcs[dev->id_unit];
216 if (dev->id_drq != -1)
217 isa_dmacascade(dev->id_drq);
218
219 /* Allocate our parent dmatag */
220 filter = NULL;
221 filter_arg = NULL;
222 lowaddr = BUS_SPACE_MAXADDR_24BIT;
223
224 if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/0, /*boundary*/0,
225 lowaddr, /*highaddr*/BUS_SPACE_MAXADDR,
226 filter, filter_arg,
227 /*maxsize*/BUS_SPACE_MAXSIZE_24BIT,
228 /*nsegments*/BUS_SPACE_UNRESTRICTED,
229 /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT,
230 /*flags*/0, &aha->parent_dmat) != 0) {
231 aha_free(aha);
232 return (-1);
233 }
234
235 if (aha_init(aha)) {
236 printf("aha init failed\n");
237 aha_free(aha);
238 return (-1);
239 }
240
241 return (aha_attach(aha));
242}
243
244/*
245 * Handle an ISA interrupt.
246 * XXX should go away as soon as ISA interrupt handlers
247 * take a (void *) arg.
248 */
249static void
250aha_isa_intr(void *unit)
251{
252 struct aha_softc* arg = aha_softcs[(int)unit];
253 aha_intr((void *)arg);
254}