adv_isa.c (56178) | adv_isa.c (59082) |
---|---|
1/* 2 * Device probe and attach routines for the following 3 * Advanced Systems Inc. SCSI controllers: 4 * 5 * Connectivity Products: 6 * ABP510/5150 - Bus-Master ISA (240 CDB) * 7 * ABP5140 - Bus-Master ISA PnP (16 CDB) * ** 8 * ABP5142 - Bus-Master ISA PnP with floppy (16 CDB) *** --- 30 unchanged lines hidden (view full) --- 39 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 45 * SUCH DAMAGE. 46 * | 1/* 2 * Device probe and attach routines for the following 3 * Advanced Systems Inc. SCSI controllers: 4 * 5 * Connectivity Products: 6 * ABP510/5150 - Bus-Master ISA (240 CDB) * 7 * ABP5140 - Bus-Master ISA PnP (16 CDB) * ** 8 * ABP5142 - Bus-Master ISA PnP with floppy (16 CDB) *** --- 30 unchanged lines hidden (view full) --- 39 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 45 * SUCH DAMAGE. 46 * |
47 * $FreeBSD: head/sys/dev/advansys/adv_isa.c 56178 2000-01-17 12:49:54Z nyan $ | 47 * $FreeBSD: head/sys/dev/advansys/adv_isa.c 59082 2000-04-07 11:32:42Z nyan $ |
48 */ 49 50#include <sys/param.h> 51#include <sys/systm.h> | 48 */ 49 50#include <sys/param.h> 51#include <sys/systm.h> |
52#include <sys/kernel.h> |
|
52 53#include <machine/bus_pio.h> 54#include <machine/bus.h> | 53 54#include <machine/bus_pio.h> 55#include <machine/bus.h> |
56#include <machine/resource.h> 57#include <sys/bus.h> 58#include <sys/rman.h> |
|
55 | 59 |
56#include <i386/isa/isa_device.h> | 60#include <isa/isavar.h> |
57 58#include <dev/advansys/advansys.h> 59 60#include <cam/scsi/scsi_all.h> 61 62#define ADV_ISA_MAX_DMA_ADDR (0x00FFFFFFL) 63#define ADV_ISA_MAX_DMA_COUNT (0x00FFFFFFL) 64 --- 21 unchanged lines hidden (view full) --- 86 0x210, /* Fifth selection in BIOS setup */ 87 0x230, /* Sixth selection in BIOS setup */ 88 0x250, /* Seventh selection in BIOS setup */ 89 0x330 /* Eighth and default selection in BIOS setup */ 90}; 91 92#define MAX_ISA_IOPORT_INDEX (sizeof(adv_isa_ioports)/sizeof(u_int16_t) - 1) 93 | 61 62#include <dev/advansys/advansys.h> 63 64#include <cam/scsi/scsi_all.h> 65 66#define ADV_ISA_MAX_DMA_ADDR (0x00FFFFFFL) 67#define ADV_ISA_MAX_DMA_COUNT (0x00FFFFFFL) 68 --- 21 unchanged lines hidden (view full) --- 90 0x210, /* Fifth selection in BIOS setup */ 91 0x230, /* Sixth selection in BIOS setup */ 92 0x250, /* Seventh selection in BIOS setup */ 93 0x330 /* Eighth and default selection in BIOS setup */ 94}; 95 96#define MAX_ISA_IOPORT_INDEX (sizeof(adv_isa_ioports)/sizeof(u_int16_t) - 1) 97 |
94static int advisaprobe(struct isa_device *id); 95static int advisaattach(struct isa_device *id); | 98static int adv_isa_probe(device_t dev); 99static int adv_isa_attach(device_t dev); |
96static void adv_set_isapnp_wait_for_key(void); 97static int adv_get_isa_dma_channel(struct adv_softc *adv); 98static int adv_set_isa_dma_settings(struct adv_softc *adv); 99 | 100static void adv_set_isapnp_wait_for_key(void); 101static int adv_get_isa_dma_channel(struct adv_softc *adv); 102static int adv_set_isa_dma_settings(struct adv_softc *adv); 103 |
100static void adv_isa_intr(void *unit); 101 102struct isa_driver advdriver = 103{ 104 advisaprobe, 105 advisaattach, 106 "adv" 107}; 108 | |
109static int | 104static int |
110advisaprobe(struct isa_device *id) | 105adv_isa_probe(device_t dev) |
111{ 112 int port_index; 113 int max_port_index; | 106{ 107 int port_index; 108 int max_port_index; |
109 u_long iobase, irq; 110 int rid = 0; 111 void *ih; 112 struct resource *iores, *irqres; |
|
114 115 /* 116 * Default to scanning all possible device locations. 117 */ 118 port_index = 0; 119 max_port_index = MAX_ISA_IOPORT_INDEX; 120 | 113 114 /* 115 * Default to scanning all possible device locations. 116 */ 117 port_index = 0; 118 max_port_index = MAX_ISA_IOPORT_INDEX; 119 |
121 if (id->id_iobase > 0) { | 120 if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) == 0) { |
122 for (;port_index <= max_port_index; port_index++) | 121 for (;port_index <= max_port_index; port_index++) |
123 if (id->id_iobase <= adv_isa_ioports[port_index]) | 122 if (iobase <= adv_isa_ioports[port_index]) |
124 break; 125 if ((port_index > max_port_index) | 123 break; 124 if ((port_index > max_port_index) |
126 || (id->id_iobase != adv_isa_ioports[port_index])) { 127 printf("adv%d: Invalid baseport of 0x%x specified. " | 125 || (iobase != adv_isa_ioports[port_index])) { 126 printf("adv%d: Invalid baseport of 0x%lx specified. " |
128 "Neerest valid baseport is 0x%x. Failing " | 127 "Neerest valid baseport is 0x%x. Failing " |
129 "probe.\n", id->id_unit, id->id_iobase, | 128 "probe.\n", device_get_unit(dev), iobase, |
130 (port_index <= max_port_index) ? 131 adv_isa_ioports[port_index] : 132 adv_isa_ioports[max_port_index]); | 129 (port_index <= max_port_index) ? 130 adv_isa_ioports[port_index] : 131 adv_isa_ioports[max_port_index]); |
133 return 0; | 132 return ENXIO; |
134 } 135 max_port_index = port_index; 136 } 137 138 /* Perform the actual probing */ 139 adv_set_isapnp_wait_for_key(); 140 for (;port_index <= max_port_index; port_index++) { 141 u_int16_t port_addr = adv_isa_ioports[port_index]; 142 bus_size_t maxsegsz; 143 bus_size_t maxsize; 144 bus_addr_t lowaddr; 145 int error; 146 147 if (port_addr == 0) 148 /* Already been attached */ 149 continue; | 133 } 134 max_port_index = port_index; 135 } 136 137 /* Perform the actual probing */ 138 adv_set_isapnp_wait_for_key(); 139 for (;port_index <= max_port_index; port_index++) { 140 u_int16_t port_addr = adv_isa_ioports[port_index]; 141 bus_size_t maxsegsz; 142 bus_size_t maxsize; 143 bus_addr_t lowaddr; 144 int error; 145 146 if (port_addr == 0) 147 /* Already been attached */ 148 continue; |
150 id->id_iobase = port_addr; 151 if (haveseen_iobase(id, 1)) /* XXX real portsize? */ | 149 150 if (bus_set_resource(dev, SYS_RES_IOPORT, 0, port_addr, 1)) |
152 continue; 153 | 151 continue; 152 |
154 if (adv_find_signature(I386_BUS_SPACE_IO, port_addr)) { | 153 /* XXX what is the real portsize? */ 154 iores = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, 155 RF_ACTIVE); 156 if (iores == NULL) 157 continue; 158 159 if (adv_find_signature(rman_get_bustag(iores), 160 rman_get_bushandle(iores))) { |
155 /* 156 * Got one. Now allocate our softc 157 * and see if we can initialize the card. 158 */ 159 struct adv_softc *adv; | 161 /* 162 * Got one. Now allocate our softc 163 * and see if we can initialize the card. 164 */ 165 struct adv_softc *adv; |
160 adv = adv_alloc(id->id_unit, I386_BUS_SPACE_IO, 161 port_addr); | 166 adv = adv_alloc(dev, rman_get_bustag(iores), 167 rman_get_bushandle(iores)); |
162 if (adv == NULL) | 168 if (adv == NULL) |
163 return (0); | 169 return ENXIO; |
164 | 170 |
165 adv_unit++; 166 167 id->id_iobase = adv->bsh; 168 | |
169 /* 170 * Stop the chip. 171 */ 172 ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT); 173 ADV_OUTW(adv, ADV_CHIP_STATUS, 0); 174 /* 175 * Determine the chip version. 176 */ 177 adv->chip_version = ADV_INB(adv, 178 ADV_NONEISA_CHIP_REVISION); 179 if ((adv->chip_version >= ADV_CHIP_MIN_VER_VL) 180 && (adv->chip_version <= ADV_CHIP_MAX_VER_VL)) { 181 adv->type = ADV_VL; 182 maxsegsz = ADV_VL_MAX_DMA_COUNT; 183 maxsize = BUS_SPACE_MAXSIZE_32BIT; 184 lowaddr = ADV_VL_MAX_DMA_ADDR; | 171 /* 172 * Stop the chip. 173 */ 174 ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT); 175 ADV_OUTW(adv, ADV_CHIP_STATUS, 0); 176 /* 177 * Determine the chip version. 178 */ 179 adv->chip_version = ADV_INB(adv, 180 ADV_NONEISA_CHIP_REVISION); 181 if ((adv->chip_version >= ADV_CHIP_MIN_VER_VL) 182 && (adv->chip_version <= ADV_CHIP_MAX_VER_VL)) { 183 adv->type = ADV_VL; 184 maxsegsz = ADV_VL_MAX_DMA_COUNT; 185 maxsize = BUS_SPACE_MAXSIZE_32BIT; 186 lowaddr = ADV_VL_MAX_DMA_ADDR; |
185 id->id_drq = -1; | 187 bus_delete_resource(dev, SYS_RES_DRQ, 0); |
186 } else if ((adv->chip_version >= ADV_CHIP_MIN_VER_ISA) 187 && (adv->chip_version <= ADV_CHIP_MAX_VER_ISA)) { 188 if (adv->chip_version >= ADV_CHIP_MIN_VER_ISA_PNP) { 189 adv->type = ADV_ISAPNP; 190 ADV_OUTB(adv, ADV_REG_IFC, 191 ADV_IFC_INIT_DEFAULT); 192 } else { 193 adv->type = ADV_ISA; 194 } 195 maxsegsz = ADV_ISA_MAX_DMA_COUNT; 196 maxsize = BUS_SPACE_MAXSIZE_24BIT; 197 lowaddr = ADV_ISA_MAX_DMA_ADDR; 198 adv->isa_dma_speed = ADV_DEF_ISA_DMA_SPEED; 199 adv->isa_dma_channel = 200 adv_get_isa_dma_channel(adv); | 188 } else if ((adv->chip_version >= ADV_CHIP_MIN_VER_ISA) 189 && (adv->chip_version <= ADV_CHIP_MAX_VER_ISA)) { 190 if (adv->chip_version >= ADV_CHIP_MIN_VER_ISA_PNP) { 191 adv->type = ADV_ISAPNP; 192 ADV_OUTB(adv, ADV_REG_IFC, 193 ADV_IFC_INIT_DEFAULT); 194 } else { 195 adv->type = ADV_ISA; 196 } 197 maxsegsz = ADV_ISA_MAX_DMA_COUNT; 198 maxsize = BUS_SPACE_MAXSIZE_24BIT; 199 lowaddr = ADV_ISA_MAX_DMA_ADDR; 200 adv->isa_dma_speed = ADV_DEF_ISA_DMA_SPEED; 201 adv->isa_dma_channel = 202 adv_get_isa_dma_channel(adv); |
201 id->id_drq = adv->isa_dma_channel; | 203 bus_set_resource(dev, SYS_RES_DRQ, 0, 204 adv->isa_dma_channel, 1); |
202 } else { 203 panic("advisaprobe: Unknown card revision\n"); 204 } 205 206 /* 207 * Allocate a parent dmatag for all tags created 208 * by the MI portions of the advansys driver 209 */ --- 11 unchanged lines hidden (view full) --- 221 maxsegsz, 222 /*flags*/0, 223 &adv->parent_dmat); 224 225 if (error != 0) { 226 printf("%s: Could not allocate DMA tag - error %d\n", 227 adv_name(adv), error); 228 adv_free(adv); | 205 } else { 206 panic("advisaprobe: Unknown card revision\n"); 207 } 208 209 /* 210 * Allocate a parent dmatag for all tags created 211 * by the MI portions of the advansys driver 212 */ --- 11 unchanged lines hidden (view full) --- 224 maxsegsz, 225 /*flags*/0, 226 &adv->parent_dmat); 227 228 if (error != 0) { 229 printf("%s: Could not allocate DMA tag - error %d\n", 230 adv_name(adv), error); 231 adv_free(adv); |
229 return (0); | 232 return ENXIO; |
230 } 231 232 adv->init_level++; 233 234 if (overrun_buf == NULL) { 235 /* Need to allocate our overrun buffer */ 236 if (bus_dma_tag_create(adv->parent_dmat, 237 /*alignment*/8, 238 /*boundary*/0, 239 ADV_ISA_MAX_DMA_ADDR, 240 BUS_SPACE_MAXADDR, 241 /*filter*/NULL, 242 /*filterarg*/NULL, 243 ADV_OVERRUN_BSIZE, 244 /*nsegments*/1, 245 BUS_SPACE_MAXSIZE_32BIT, 246 /*flags*/0, 247 &overrun_dmat) != 0) { 248 adv_free(adv); | 233 } 234 235 adv->init_level++; 236 237 if (overrun_buf == NULL) { 238 /* Need to allocate our overrun buffer */ 239 if (bus_dma_tag_create(adv->parent_dmat, 240 /*alignment*/8, 241 /*boundary*/0, 242 ADV_ISA_MAX_DMA_ADDR, 243 BUS_SPACE_MAXADDR, 244 /*filter*/NULL, 245 /*filterarg*/NULL, 246 ADV_OVERRUN_BSIZE, 247 /*nsegments*/1, 248 BUS_SPACE_MAXSIZE_32BIT, 249 /*flags*/0, 250 &overrun_dmat) != 0) { 251 adv_free(adv); |
249 return (0); | 252 return ENXIO; |
250 } 251 if (bus_dmamem_alloc(overrun_dmat, 252 (void **)&overrun_buf, 253 BUS_DMA_NOWAIT, 254 &overrun_dmamap) != 0) { 255 bus_dma_tag_destroy(overrun_dmat); 256 adv_free(adv); | 253 } 254 if (bus_dmamem_alloc(overrun_dmat, 255 (void **)&overrun_buf, 256 BUS_DMA_NOWAIT, 257 &overrun_dmamap) != 0) { 258 bus_dma_tag_destroy(overrun_dmat); 259 adv_free(adv); |
257 return (0); | 260 return ENXIO; |
258 } 259 /* And permanently map it in */ 260 bus_dmamap_load(overrun_dmat, overrun_dmamap, 261 overrun_buf, ADV_OVERRUN_BSIZE, 262 adv_map, &overrun_physbase, 263 /*flags*/0); 264 } 265 266 adv->overrun_physbase = overrun_physbase; 267 268 if (adv_init(adv) != 0) { 269 adv_free(adv); | 261 } 262 /* And permanently map it in */ 263 bus_dmamap_load(overrun_dmat, overrun_dmamap, 264 overrun_buf, ADV_OVERRUN_BSIZE, 265 adv_map, &overrun_physbase, 266 /*flags*/0); 267 } 268 269 adv->overrun_physbase = overrun_physbase; 270 271 if (adv_init(adv) != 0) { 272 adv_free(adv); |
270 return (0); | 273 return ENXIO; |
271 } 272 273 switch (adv->type) { 274 case ADV_ISAPNP: 275 if (adv->chip_version == ADV_CHIP_VER_ASYN_BUG){ 276 adv->bug_fix_control 277 |= ADV_BUG_FIX_ASYN_USE_SYN; 278 adv->fix_asyn_xfer = ~0; --- 9 unchanged lines hidden (view full) --- 288 adv->max_dma_count = ADV_VL_MAX_DMA_COUNT; 289 adv->max_dma_addr = ADV_VL_MAX_DMA_ADDR; 290 break; 291 default: 292 panic("advisaprobe: Invalid card type\n"); 293 } 294 295 /* Determine our IRQ */ | 274 } 275 276 switch (adv->type) { 277 case ADV_ISAPNP: 278 if (adv->chip_version == ADV_CHIP_VER_ASYN_BUG){ 279 adv->bug_fix_control 280 |= ADV_BUG_FIX_ASYN_USE_SYN; 281 adv->fix_asyn_xfer = ~0; --- 9 unchanged lines hidden (view full) --- 291 adv->max_dma_count = ADV_VL_MAX_DMA_COUNT; 292 adv->max_dma_addr = ADV_VL_MAX_DMA_ADDR; 293 break; 294 default: 295 panic("advisaprobe: Invalid card type\n"); 296 } 297 298 /* Determine our IRQ */ |
296 if (id->id_irq == 0 /* irq ? */) 297 id->id_irq = 1 << adv_get_chip_irq(adv); | 299 if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL)) 300 bus_set_resource(dev, SYS_RES_IRQ, 0, 301 adv_get_chip_irq(adv), 1); |
298 else | 302 else |
299 adv_set_chip_irq(adv, ffs(id->id_irq) - 1); | 303 adv_set_chip_irq(adv, irq); |
300 | 304 |
301 id->id_intr = adv_isa_intr; 302 | 305 irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 306 0, ~0, 1, RF_ACTIVE); 307 if (irqres == NULL || 308 bus_setup_intr(dev, irqres, INTR_TYPE_CAM, 309 adv_intr, adv, &ih)) { 310 adv_free(adv); 311 return ENXIO; 312 } 313 |
303 /* Mark as probed */ 304 adv_isa_ioports[port_index] = 0; | 314 /* Mark as probed */ 315 adv_isa_ioports[port_index] = 0; |
305 return 1; /* XXX what is the real portsize? */ | 316 return 0; |
306 } 307 } 308 | 317 } 318 } 319 |
309 return 0; | 320 return ENXIO; |
310} 311 312static int | 321} 322 323static int |
313advisaattach(struct isa_device *id) | 324adv_isa_attach(device_t dev) |
314{ | 325{ |
315 struct adv_softc *adv; | 326 struct adv_softc *adv = device_get_softc(dev); |
316 | 327 |
317 adv = advsoftcs[id->id_unit]; | |
318 return (adv_attach(adv)); 319} 320 321static int 322adv_get_isa_dma_channel(struct adv_softc *adv) 323{ 324 int channel; 325 --- 34 unchanged lines hidden (view full) --- 360adv_set_isapnp_wait_for_key(void) 361{ 362 static int isapnp_wait_set = 0; 363 if (isapnp_wait_set == 0) { 364 outb(ADV_ISA_PNP_PORT_ADDR, 0x02); 365 outb(ADV_ISA_PNP_PORT_WRITE, 0x02); 366 isapnp_wait_set++; 367 } | 328 return (adv_attach(adv)); 329} 330 331static int 332adv_get_isa_dma_channel(struct adv_softc *adv) 333{ 334 int channel; 335 --- 34 unchanged lines hidden (view full) --- 370adv_set_isapnp_wait_for_key(void) 371{ 372 static int isapnp_wait_set = 0; 373 if (isapnp_wait_set == 0) { 374 outb(ADV_ISA_PNP_PORT_ADDR, 0x02); 375 outb(ADV_ISA_PNP_PORT_WRITE, 0x02); 376 isapnp_wait_set++; 377 } |
368 return; | |
369} 370 | 378} 379 |
371/* 372 * Handle an ISA interrupt. 373 * XXX should go away as soon as ISA interrupt handlers 374 * take a (void *) arg. 375 */ 376static void 377adv_isa_intr(void *unit) 378{ 379 struct adv_softc *arg = advsoftcs[(int)unit]; 380 adv_intr((void *)arg); 381} | 380static device_method_t adv_isa_methods[] = { 381 /* Device interface */ 382 DEVMETHOD(device_probe, adv_isa_probe), 383 DEVMETHOD(device_attach, adv_isa_attach), 384 { 0, 0 } 385}; 386 387static driver_t adv_isa_driver = { 388 "adv", adv_isa_methods, sizeof(struct adv_softc) 389}; 390 391static devclass_t adv_isa_devclass; 392DRIVER_MODULE(adv, isa, adv_isa_driver, adv_isa_devclass, 0, 0); |