1/* 2 * Product specific probe and attach routines for: 3 * Buslogic BT-54X and BT-445 cards 4 * 5 * Copyright (c) 1998 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, this list of conditions, and the following disclaimer, 13 * without modification, immediately at the beginning of the file. 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 * Product specific probe and attach routines for: 3 * Buslogic BT-54X and BT-445 cards 4 * 5 * Copyright (c) 1998 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, this list of conditions, and the following disclaimer, 13 * without modification, immediately at the beginning of the file. 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: bt_isa.c,v 1.2 1998/09/24 10:43:42 bde Exp $
| 29 * $Id: bt_isa.c,v 1.3 1998/10/10 00:44:12 imp Exp $
|
30 */ 31 32#include <sys/param.h> 33#include <sys/systm.h> 34 35#include <machine/bus_pio.h> 36#include <machine/bus.h> 37 38#include <i386/isa/isa_device.h> 39#include <dev/buslogic/btreg.h> 40 41#include <cam/scsi/scsi_all.h> 42 43static int bt_isa_probe __P((struct isa_device *dev)); 44static int bt_isa_attach __P((struct isa_device *dev)); 45static void bt_isa_intr __P((void *unit)); 46 47static bus_dma_filter_t btvlbouncefilter; 48static bus_dmamap_callback_t btmapsensebuffers; 49 50struct isa_driver btdriver = 51{ 52 bt_isa_probe, 53 bt_isa_attach, 54 "bt" 55}; 56 57/* 58 * Check if the device can be found at the port given 59 * and if so, set it up ready for further work 60 * as an argument, takes the isa_device structure from 61 * autoconf.c 62 */ 63static int 64bt_isa_probe(dev) 65 struct isa_device *dev; 66{ 67 /* 68 * find unit and check we have that many defined 69 */ 70 struct bt_softc *bt; 71 int port_index; 72 int max_port_index; 73 74 /* 75 * We ignore the unit number assigned by config to allow 76 * consistant numbering between PCI/EISA/ISA devices. 77 * This is a total kludge until we have a configuration 78 * manager. 79 */ 80 dev->id_unit = bt_unit; 81 82 bt = NULL; 83 port_index = 0; 84 max_port_index = BT_NUM_ISAPORTS - 1; 85 /* 86 * Bound our board search if the user has 87 * specified an exact port. 88 */ 89 if (dev->id_iobase > 0) { 90 for (;port_index <= max_port_index; port_index++) 91 if (dev->id_iobase >= bt_isa_ports[port_index].addr) 92 break; 93 if ((port_index > max_port_index) 94 || (dev->id_iobase != bt_isa_ports[port_index].addr)) { 95 printf(" 96bt_isa_probe: Invalid baseport of 0x%x specified. 97bt_isa_probe: Nearest valid baseport is 0x%x. 98bt_isa_probe: Failing probe.\n", 99 dev->id_iobase, 100 (port_index <= max_port_index) 101 ? bt_isa_ports[port_index].addr 102 : bt_isa_ports[max_port_index].addr); 103 return 0; 104 } 105 max_port_index = port_index; 106 } 107 108 /* Attempt to find an adapter */ 109 for (;port_index <= max_port_index; port_index++) { 110 config_data_t config_data; 111 u_int ioport; 112 int error; 113 114 ioport = bt_isa_ports[port_index].addr; 115 116 /* 117 * Ensure this port has not already been claimed already
| 30 */ 31 32#include <sys/param.h> 33#include <sys/systm.h> 34 35#include <machine/bus_pio.h> 36#include <machine/bus.h> 37 38#include <i386/isa/isa_device.h> 39#include <dev/buslogic/btreg.h> 40 41#include <cam/scsi/scsi_all.h> 42 43static int bt_isa_probe __P((struct isa_device *dev)); 44static int bt_isa_attach __P((struct isa_device *dev)); 45static void bt_isa_intr __P((void *unit)); 46 47static bus_dma_filter_t btvlbouncefilter; 48static bus_dmamap_callback_t btmapsensebuffers; 49 50struct isa_driver btdriver = 51{ 52 bt_isa_probe, 53 bt_isa_attach, 54 "bt" 55}; 56 57/* 58 * Check if the device can be found at the port given 59 * and if so, set it up ready for further work 60 * as an argument, takes the isa_device structure from 61 * autoconf.c 62 */ 63static int 64bt_isa_probe(dev) 65 struct isa_device *dev; 66{ 67 /* 68 * find unit and check we have that many defined 69 */ 70 struct bt_softc *bt; 71 int port_index; 72 int max_port_index; 73 74 /* 75 * We ignore the unit number assigned by config to allow 76 * consistant numbering between PCI/EISA/ISA devices. 77 * This is a total kludge until we have a configuration 78 * manager. 79 */ 80 dev->id_unit = bt_unit; 81 82 bt = NULL; 83 port_index = 0; 84 max_port_index = BT_NUM_ISAPORTS - 1; 85 /* 86 * Bound our board search if the user has 87 * specified an exact port. 88 */ 89 if (dev->id_iobase > 0) { 90 for (;port_index <= max_port_index; port_index++) 91 if (dev->id_iobase >= bt_isa_ports[port_index].addr) 92 break; 93 if ((port_index > max_port_index) 94 || (dev->id_iobase != bt_isa_ports[port_index].addr)) { 95 printf(" 96bt_isa_probe: Invalid baseport of 0x%x specified. 97bt_isa_probe: Nearest valid baseport is 0x%x. 98bt_isa_probe: Failing probe.\n", 99 dev->id_iobase, 100 (port_index <= max_port_index) 101 ? bt_isa_ports[port_index].addr 102 : bt_isa_ports[max_port_index].addr); 103 return 0; 104 } 105 max_port_index = port_index; 106 } 107 108 /* Attempt to find an adapter */ 109 for (;port_index <= max_port_index; port_index++) { 110 config_data_t config_data; 111 u_int ioport; 112 int error; 113 114 ioport = bt_isa_ports[port_index].addr; 115 116 /* 117 * Ensure this port has not already been claimed already
|
118 * by a PCI or EISA adapter.
| 118 * by a PCI, EISA or ISA adapter.
|
119 */ 120 if (bt_check_probed_iop(ioport) != 0) 121 continue;
| 119 */ 120 if (bt_check_probed_iop(ioport) != 0) 121 continue;
|
122 123 /* 124 * Make sure that we do not conflict with another device's 125 * I/O address. 126 */ 127 if (haveseen_isadev(dev, CC_IOADDR))
| 122 dev->id_iobase = bt_isa_ports[port_index].addr; 123 if (haveseen_isadev(dev, CC_IOADDR | CC_QUIET))
|
128 continue; 129 130 /* Allocate a softc for use during probing */ 131 bt = bt_alloc(dev->id_unit, I386_BUS_SPACE_IO, ioport); 132 133 if (bt == NULL) 134 break; 135 136 /* We're going to attempt to probe it now, so mark it probed */ 137 bt_mark_probed_bio(port_index); 138 139 /* See if there is really a card present */ 140 if (bt_probe(bt) || bt_fetch_adapter_info(bt)) { 141 bt_free(bt); 142 continue; 143 } 144 145 /* 146 * Determine our IRQ, and DMA settings and 147 * export them to the configuration system. 148 */ 149 error = bt_cmd(bt, BOP_INQUIRE_CONFIG, NULL, /*parmlen*/0, 150 (u_int8_t*)&config_data, sizeof(config_data), 151 DEFAULT_CMD_TIMEOUT); 152 if (error != 0) { 153 printf("bt_isa_probe: Could not determine IRQ or DMA " 154 "settings for adapter at 0x%x. Failing probe\n", 155 ioport); 156 bt_free(bt); 157 continue; 158 } 159 160 if (bt->model[0] == '5') { 161 /* DMA settings only make sense for ISA cards */ 162 switch (config_data.dma_chan) { 163 case DMA_CHAN_5: 164 dev->id_drq = 5; 165 break; 166 case DMA_CHAN_6: 167 dev->id_drq = 6; 168 break; 169 case DMA_CHAN_7: 170 dev->id_drq = 7; 171 break; 172 default: 173 printf("bt_isa_probe: Invalid DMA setting " 174 "detected for adapter at 0x%x. " 175 "Failing probe\n", ioport); 176 } 177 } else { 178 /* VL DMA */ 179 dev->id_drq = -1; 180 }
| 124 continue; 125 126 /* Allocate a softc for use during probing */ 127 bt = bt_alloc(dev->id_unit, I386_BUS_SPACE_IO, ioport); 128 129 if (bt == NULL) 130 break; 131 132 /* We're going to attempt to probe it now, so mark it probed */ 133 bt_mark_probed_bio(port_index); 134 135 /* See if there is really a card present */ 136 if (bt_probe(bt) || bt_fetch_adapter_info(bt)) { 137 bt_free(bt); 138 continue; 139 } 140 141 /* 142 * Determine our IRQ, and DMA settings and 143 * export them to the configuration system. 144 */ 145 error = bt_cmd(bt, BOP_INQUIRE_CONFIG, NULL, /*parmlen*/0, 146 (u_int8_t*)&config_data, sizeof(config_data), 147 DEFAULT_CMD_TIMEOUT); 148 if (error != 0) { 149 printf("bt_isa_probe: Could not determine IRQ or DMA " 150 "settings for adapter at 0x%x. Failing probe\n", 151 ioport); 152 bt_free(bt); 153 continue; 154 } 155 156 if (bt->model[0] == '5') { 157 /* DMA settings only make sense for ISA cards */ 158 switch (config_data.dma_chan) { 159 case DMA_CHAN_5: 160 dev->id_drq = 5; 161 break; 162 case DMA_CHAN_6: 163 dev->id_drq = 6; 164 break; 165 case DMA_CHAN_7: 166 dev->id_drq = 7; 167 break; 168 default: 169 printf("bt_isa_probe: Invalid DMA setting " 170 "detected for adapter at 0x%x. " 171 "Failing probe\n", ioport); 172 } 173 } else { 174 /* VL DMA */ 175 dev->id_drq = -1; 176 }
|
181 dev->id_iobase = bt_isa_ports[port_index].addr;
| |
182 dev->id_irq = (config_data.irq << 9); 183 dev->id_intr = bt_isa_intr; 184
| 177 dev->id_irq = (config_data.irq << 9); 178 dev->id_intr = bt_isa_intr; 179
|
185 /* 186 * OK, check to make sure that we're not stepping on 187 * someone else's IRQ or DRQ 188 */ 189 if (haveseen_isadev(dev, CC_DRQ)) { 190 printf("bt_isa_probe: Bt card at I/O 0x%x's drq %d " 191 "conflicts, ignoring card.\n", dev->id_iobase, 192 dev->id_drq); 193 bt_free(bt); 194 return 0; 195 } 196 if (haveseen_isadev(dev, CC_IRQ)) { 197 printf("bt_isa_probe: Bt card at I/O 0x%x's irq %d " 198 "conflicts, ignoring card.\n", dev->id_iobase, 199 config_data.irq + 9); 200 bt_free(bt); 201 return 0; 202 }
| |
203 bt_unit++; 204 return (BT_NREGS); 205 } 206 207 return (0); 208} 209 210/* 211 * Attach all the sub-devices we can find 212 */ 213static int 214bt_isa_attach(dev) 215 struct isa_device *dev; 216{ 217 struct bt_softc *bt; 218 bus_dma_filter_t *filter; 219 void *filter_arg; 220 bus_addr_t lowaddr; 221 222 bt = bt_softcs[dev->id_unit]; 223 if (dev->id_drq != -1) 224 isa_dmacascade(dev->id_drq); 225 226 /* Allocate our parent dmatag */ 227 filter = NULL; 228 filter_arg = NULL; 229 lowaddr = BUS_SPACE_MAXADDR_24BIT; 230 if (bt->model[0] == '4') { 231 /* 232 * This is a VL adapter. Typically, VL devices have access 233 * to the full 32bit address space. On BT-445S adapters 234 * prior to revision E, there is a hardware bug that causes 235 * corruption of transfers to/from addresses in the range of 236 * the BIOS modulo 16MB. The only properly functioning 237 * BT-445S Host Adapters have firmware version 3.37. 238 * If we encounter one of these adapters and the BIOS is 239 * installed, install a filter function for our bus_dma_map 240 * that will catch these accesses and bounce them to a safe 241 * region of memory. 242 */ 243 if (bt->bios_addr != 0 244 && strcmp(bt->model, "445S") == 0 245 && strcmp(bt->firmware_ver, "3.37") < 0) { 246 filter = btvlbouncefilter; 247 filter_arg = bt; 248 } else { 249 lowaddr = BUS_SPACE_MAXADDR_32BIT; 250 } 251 } 252 253 /* XXX Should be a child of the ISA or VL bus dma tag */ 254 if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/0, /*boundary*/0, 255 lowaddr, /*highaddr*/BUS_SPACE_MAXADDR, 256 filter, filter_arg, 257 /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, 258 /*nsegments*/BUS_SPACE_UNRESTRICTED, 259 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 260 /*flags*/0, &bt->parent_dmat) != 0) { 261 bt_free(bt); 262 return (-1); 263 } 264 265 if (bt_init(bt)) { 266 bt_free(bt); 267 return (-1); 268 } 269 270 if (lowaddr != BUS_SPACE_MAXADDR_32BIT) { 271 /* DMA tag for our sense buffers */ 272 if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/0, 273 /*boundary*/0, 274 /*lowaddr*/BUS_SPACE_MAXADDR, 275 /*highaddr*/BUS_SPACE_MAXADDR, 276 /*filter*/NULL, /*filterarg*/NULL, 277 bt->max_ccbs 278 * sizeof(struct scsi_sense_data), 279 /*nsegments*/1, 280 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 281 /*flags*/0, &bt->sense_dmat) != 0) { 282 bt_free(bt); 283 return (-1); 284 } 285 286 bt->init_level++; 287 288 /* Allocation of sense buffers */ 289 if (bus_dmamem_alloc(bt->sense_dmat, 290 (void **)&bt->sense_buffers, 291 BUS_DMA_NOWAIT, &bt->sense_dmamap) != 0) { 292 bt_free(bt); 293 return (-1); 294 } 295 296 bt->init_level++; 297 298 /* And permanently map them */ 299 bus_dmamap_load(bt->sense_dmat, bt->sense_dmamap, 300 bt->sense_buffers, 301 bt->max_ccbs * sizeof(*bt->sense_buffers), 302 btmapsensebuffers, bt, /*flags*/0); 303 304 bt->init_level++; 305 } 306 307 return (bt_attach(bt)); 308} 309 310/* 311 * Handle an ISA interrupt. 312 * XXX should go away as soon as ISA interrupt handlers 313 * take a (void *) arg. 314 */ 315static void 316bt_isa_intr(void *unit) 317{ 318 struct bt_softc* arg = bt_softcs[(int)unit]; 319 bt_intr((void *)arg); 320} 321 322#define BIOS_MAP_SIZE (16 * 1024) 323 324static int 325btvlbouncefilter(void *arg, bus_addr_t addr) 326{ 327 struct bt_softc *bt; 328 329 bt = (struct bt_softc *)arg; 330 331 addr &= BUS_SPACE_MAXADDR_24BIT; 332 333 if (addr == 0 334 || (addr >= bt->bios_addr 335 && addr < (bt->bios_addr + BIOS_MAP_SIZE))) 336 return (1); 337 return (0); 338} 339 340static void 341btmapsensebuffers(void *arg, bus_dma_segment_t *segs, int nseg, int error) 342{ 343 struct bt_softc* bt; 344 345 bt = (struct bt_softc*)arg; 346 bt->sense_buffers_physbase = segs->ds_addr; 347}
| 180 bt_unit++; 181 return (BT_NREGS); 182 } 183 184 return (0); 185} 186 187/* 188 * Attach all the sub-devices we can find 189 */ 190static int 191bt_isa_attach(dev) 192 struct isa_device *dev; 193{ 194 struct bt_softc *bt; 195 bus_dma_filter_t *filter; 196 void *filter_arg; 197 bus_addr_t lowaddr; 198 199 bt = bt_softcs[dev->id_unit]; 200 if (dev->id_drq != -1) 201 isa_dmacascade(dev->id_drq); 202 203 /* Allocate our parent dmatag */ 204 filter = NULL; 205 filter_arg = NULL; 206 lowaddr = BUS_SPACE_MAXADDR_24BIT; 207 if (bt->model[0] == '4') { 208 /* 209 * This is a VL adapter. Typically, VL devices have access 210 * to the full 32bit address space. On BT-445S adapters 211 * prior to revision E, there is a hardware bug that causes 212 * corruption of transfers to/from addresses in the range of 213 * the BIOS modulo 16MB. The only properly functioning 214 * BT-445S Host Adapters have firmware version 3.37. 215 * If we encounter one of these adapters and the BIOS is 216 * installed, install a filter function for our bus_dma_map 217 * that will catch these accesses and bounce them to a safe 218 * region of memory. 219 */ 220 if (bt->bios_addr != 0 221 && strcmp(bt->model, "445S") == 0 222 && strcmp(bt->firmware_ver, "3.37") < 0) { 223 filter = btvlbouncefilter; 224 filter_arg = bt; 225 } else { 226 lowaddr = BUS_SPACE_MAXADDR_32BIT; 227 } 228 } 229 230 /* XXX Should be a child of the ISA or VL bus dma tag */ 231 if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/0, /*boundary*/0, 232 lowaddr, /*highaddr*/BUS_SPACE_MAXADDR, 233 filter, filter_arg, 234 /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, 235 /*nsegments*/BUS_SPACE_UNRESTRICTED, 236 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 237 /*flags*/0, &bt->parent_dmat) != 0) { 238 bt_free(bt); 239 return (-1); 240 } 241 242 if (bt_init(bt)) { 243 bt_free(bt); 244 return (-1); 245 } 246 247 if (lowaddr != BUS_SPACE_MAXADDR_32BIT) { 248 /* DMA tag for our sense buffers */ 249 if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/0, 250 /*boundary*/0, 251 /*lowaddr*/BUS_SPACE_MAXADDR, 252 /*highaddr*/BUS_SPACE_MAXADDR, 253 /*filter*/NULL, /*filterarg*/NULL, 254 bt->max_ccbs 255 * sizeof(struct scsi_sense_data), 256 /*nsegments*/1, 257 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 258 /*flags*/0, &bt->sense_dmat) != 0) { 259 bt_free(bt); 260 return (-1); 261 } 262 263 bt->init_level++; 264 265 /* Allocation of sense buffers */ 266 if (bus_dmamem_alloc(bt->sense_dmat, 267 (void **)&bt->sense_buffers, 268 BUS_DMA_NOWAIT, &bt->sense_dmamap) != 0) { 269 bt_free(bt); 270 return (-1); 271 } 272 273 bt->init_level++; 274 275 /* And permanently map them */ 276 bus_dmamap_load(bt->sense_dmat, bt->sense_dmamap, 277 bt->sense_buffers, 278 bt->max_ccbs * sizeof(*bt->sense_buffers), 279 btmapsensebuffers, bt, /*flags*/0); 280 281 bt->init_level++; 282 } 283 284 return (bt_attach(bt)); 285} 286 287/* 288 * Handle an ISA interrupt. 289 * XXX should go away as soon as ISA interrupt handlers 290 * take a (void *) arg. 291 */ 292static void 293bt_isa_intr(void *unit) 294{ 295 struct bt_softc* arg = bt_softcs[(int)unit]; 296 bt_intr((void *)arg); 297} 298 299#define BIOS_MAP_SIZE (16 * 1024) 300 301static int 302btvlbouncefilter(void *arg, bus_addr_t addr) 303{ 304 struct bt_softc *bt; 305 306 bt = (struct bt_softc *)arg; 307 308 addr &= BUS_SPACE_MAXADDR_24BIT; 309 310 if (addr == 0 311 || (addr >= bt->bios_addr 312 && addr < (bt->bios_addr + BIOS_MAP_SIZE))) 313 return (1); 314 return (0); 315} 316 317static void 318btmapsensebuffers(void *arg, bus_dma_segment_t *segs, int nseg, int error) 319{ 320 struct bt_softc* bt; 321 322 bt = (struct bt_softc*)arg; 323 bt->sense_buffers_physbase = segs->ds_addr; 324}
|