FreeBSD/Linux Kernel Cross Reference
sys/pci/aic7870.c
1 /*
2 * Product specific probe and attach routines for:
3 * 3940, 2940, aic7880, aic7870, aic7860 and aic7850 SCSI controllers
4 *
5 * Copyright (c) 1995, 1996, 1997 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. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $FreeBSD: src/sys/pci/aic7870.c,v 1.41.2.11 1999/09/05 08:20:55 peter Exp $
33 */
34
35 #if defined(__FreeBSD__)
36 #include <pci.h>
37 #endif
38 #if NPCI > 0 || defined(__NetBSD__)
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/malloc.h>
42 #include <sys/kernel.h>
43 #include <sys/queue.h>
44 #if defined(__NetBSD__)
45 #include <sys/device.h>
46 #include <machine/bus.h>
47 #include <machine/intr.h>
48 #endif /* defined(__NetBSD__) */
49
50 #include <scsi/scsi_all.h>
51 #include <scsi/scsiconf.h>
52
53 #if defined(__FreeBSD__)
54
55 #include <pci/pcireg.h>
56 #include <pci/pcivar.h>
57
58 #include <machine/clock.h>
59
60 #include <i386/scsi/aic7xxx.h>
61 #include <i386/scsi/93cx6.h>
62
63 #include <aic7xxx_reg.h>
64
65 #define PCI_BASEADR0 PCI_MAP_REG_START /* I/O Address */
66 #define PCI_BASEADR1 PCI_MAP_REG_START + 4 /* Mem I/O Address */
67
68 #elif defined(__NetBSD__)
69
70 #include <dev/pci/pcireg.h>
71 #include <dev/pci/pcivar.h>
72
73 #include <dev/ic/aic7xxxreg.h>
74 #include <dev/ic/aic7xxxvar.h>
75 #include <dev/ic/smc93cx6var.h>
76
77 #define bootverbose 1
78 #define PCI_BASEADR0 PCI_MAPREG_START /* I/O Address */
79 #define PCI_BASEADR1 PCI_MAPREG_START + 4 /* Mem I/O Address */
80
81 #endif /* defined(__NetBSD__) */
82
83 #define PCI_DEVICE_ID_ADAPTEC_398XU 0x83789004ul
84 #define PCI_DEVICE_ID_ADAPTEC_3940U 0x82789004ul
85 #define PCI_DEVICE_ID_ADAPTEC_2944U 0x84789004ul
86 #define PCI_DEVICE_ID_ADAPTEC_2940U 0x81789004ul
87 #define PCI_DEVICE_ID_ADAPTEC_2940AU 0x61789004ul
88 #define PCI_DEVICE_ID_ADAPTEC_398X 0x73789004ul
89 #define PCI_DEVICE_ID_ADAPTEC_3940 0x72789004ul
90 #define PCI_DEVICE_ID_ADAPTEC_2944 0x74789004ul
91 #define PCI_DEVICE_ID_ADAPTEC_2940 0x71789004ul
92 #define PCI_DEVICE_ID_ADAPTEC_AIC7880 0x80789004ul
93 #define PCI_DEVICE_ID_ADAPTEC_AIC7870 0x70789004ul
94 #define PCI_DEVICE_ID_ADAPTEC_AIC7860 0x60789004ul
95 #define PCI_DEVICE_ID_ADAPTEC_AIC7855 0x55789004ul
96 #define PCI_DEVICE_ID_ADAPTEC_AIC7850 0x50789004ul
97 #define PCI_DEVICE_ID_ADAPTEC_AIC7810 0x10789004ul
98
99 #define DEVCONFIG 0x40
100 #define MPORTMODE 0x00000400ul /* aic7870 only */
101 #define RAMPSM 0x00000200ul /* aic7870 only */
102 #define VOLSENSE 0x00000100ul
103 #define SCBRAMSEL 0x00000080ul
104 #define MRDCEN 0x00000040ul
105 #define EXTSCBTIME 0x00000020ul /* aic7870 only */
106 #define EXTSCBPEN 0x00000010ul /* aic7870 only */
107 #define BERREN 0x00000008ul
108 #define DACEN 0x00000004ul
109 #define STPWLEVEL 0x00000002ul
110 #define DIFACTNEGEN 0x00000001ul /* aic7870 only */
111
112 #define CSIZE_LATTIME 0x0c
113 #define CACHESIZE 0x0000003ful /* only 5 bits */
114 #define LATTIME 0x0000ff00ul
115
116 /*
117 * Define the format of the aic78X0 SEEPROM registers (16 bits).
118 */
119
120 struct seeprom_config {
121
122 /*
123 * SCSI ID Configuration Flags
124 */
125 #define CFXFER 0x0007 /* synchronous transfer rate */
126 #define CFSYNCH 0x0008 /* enable synchronous transfer */
127 #define CFDISC 0x0010 /* enable disconnection */
128 #define CFWIDEB 0x0020 /* wide bus device */
129 /* UNUSED 0x00C0 */
130 #define CFSTART 0x0100 /* send start unit SCSI command */
131 #define CFINCBIOS 0x0200 /* include in BIOS scan */
132 #define CFRNFOUND 0x0400 /* report even if not found */
133 /* UNUSED 0xf800 */
134 u_int16_t device_flags[16]; /* words 0-15 */
135
136 /*
137 * BIOS Control Bits
138 */
139 #define CFSUPREM 0x0001 /* support all removeable drives */
140 #define CFSUPREMB 0x0002 /* support removeable drives for boot only */
141 #define CFBIOSEN 0x0004 /* BIOS enabled */
142 /* UNUSED 0x0008 */
143 #define CFSM2DRV 0x0010 /* support more than two drives */
144 /* UNUSED 0x0060 */
145 #define CFEXTEND 0x0080 /* extended translation enabled */
146 /* UNUSED 0xff00 */
147 u_int16_t bios_control; /* word 16 */
148
149 /*
150 * Host Adapter Control Bits
151 */
152 #define CFAUTOTERM 0x0001 /* Perform Auto termination */
153 #define CFULTRAEN 0x0002 /* Ultra SCSI speed enable */
154 #define CFSTERM 0x0004 /* SCSI low byte termination */
155 #define CFWSTERM 0x0008 /* SCSI high byte termination */
156 #define CFSPARITY 0x0010 /* SCSI parity */
157 /* UNUSED 0x0020 */
158 #define CFRESETB 0x0040 /* reset SCSI bus at boot */
159 /* UNUSED 0xff80 */
160 u_int16_t adapter_control; /* word 17 */
161
162 /*
163 * Bus Release, Host Adapter ID
164 */
165 #define CFSCSIID 0x000f /* host adapter SCSI ID */
166 /* UNUSED 0x00f0 */
167 #define CFBRTIME 0xff00 /* bus release time */
168 u_int16_t brtime_id; /* word 18 */
169
170 /*
171 * Maximum targets
172 */
173 #define CFMAXTARG 0x00ff /* maximum targets */
174 /* UNUSED 0xff00 */
175 u_int16_t max_targets; /* word 19 */
176
177 u_int16_t res_1[11]; /* words 20-30 */
178 u_int16_t checksum; /* word 31 */
179 };
180
181 static void load_seeprom __P((struct ahc_softc *ahc, u_int8_t *sxfrctl1));
182 static int acquire_seeprom __P((struct seeprom_descriptor *sd));
183 static void release_seeprom __P((struct seeprom_descriptor *sd));
184 static void write_brdctl __P((struct ahc_softc *ahc, u_int8_t value));
185 static u_int8_t read_brdctl __P((struct ahc_softc *ahc));
186
187 static int aic3940_count;
188 static int aic398X_count;
189 static struct ahc_softc *first_398X;
190
191 #if defined(__FreeBSD__)
192
193 static char* aic7870_probe __P((pcici_t tag, pcidi_t type));
194 static void aic7870_attach __P((pcici_t config_id, int unit));
195
196 static struct pci_device ahc_pci_driver = {
197 "ahc",
198 aic7870_probe,
199 aic7870_attach,
200 &ahc_unit,
201 NULL
202 };
203
204 DATA_SET (pcidevice_set, ahc_pci_driver);
205
206 static char*
207 aic7870_probe (pcici_t tag, pcidi_t type)
208 {
209 switch (type) {
210 case PCI_DEVICE_ID_ADAPTEC_398XU:
211 return ("Adaptec 398X Ultra SCSI RAID adapter");
212 break;
213 case PCI_DEVICE_ID_ADAPTEC_3940U:
214 return ("Adaptec 3940 Ultra SCSI host adapter");
215 break;
216 case PCI_DEVICE_ID_ADAPTEC_398X:
217 return ("Adaptec 398X SCSI RAID adapter");
218 break;
219 case PCI_DEVICE_ID_ADAPTEC_3940:
220 return ("Adaptec 3940 SCSI host adapter");
221 break;
222 case PCI_DEVICE_ID_ADAPTEC_2944U:
223 return ("Adaptec 2944 Ultra SCSI host adapter");
224 break;
225 case PCI_DEVICE_ID_ADAPTEC_2940U:
226 return ("Adaptec 2940 Ultra SCSI host adapter");
227 break;
228 case PCI_DEVICE_ID_ADAPTEC_2944:
229 return ("Adaptec 2944 SCSI host adapter");
230 break;
231 case PCI_DEVICE_ID_ADAPTEC_2940:
232 return ("Adaptec 2940 SCSI host adapter");
233 break;
234 case PCI_DEVICE_ID_ADAPTEC_2940AU:
235 return ("Adaptec 2940A Ultra SCSI host adapter");
236 break;
237 case PCI_DEVICE_ID_ADAPTEC_AIC7880:
238 return ("Adaptec aic7880 Ultra SCSI host adapter");
239 break;
240 case PCI_DEVICE_ID_ADAPTEC_AIC7870:
241 return ("Adaptec aic7870 SCSI host adapter");
242 break;
243 case PCI_DEVICE_ID_ADAPTEC_AIC7860:
244 return ("Adaptec aic7860 SCSI host adapter");
245 break;
246 case PCI_DEVICE_ID_ADAPTEC_AIC7855:
247 return ("Adaptec aic7855 SCSI host adapter");
248 break;
249 case PCI_DEVICE_ID_ADAPTEC_AIC7850:
250 return ("Adaptec aic7850 SCSI host adapter");
251 break;
252 case PCI_DEVICE_ID_ADAPTEC_AIC7810:
253 return ("Adaptec aic7810 RAID memory controller");
254 break;
255 default:
256 break;
257 }
258 return (0);
259
260 }
261
262 #elif defined(__NetBSD__)
263
264 int ahc_pci_probe __P((struct device *, void *, void *));
265 void ahc_pci_attach __P((struct device *, struct device *, void *));
266
267 struct cfattach ahc_pci_ca = {
268 sizeof(struct ahc_softc), ahc_pci_probe, ahc_pci_attach
269 };
270
271 int
272 ahc_pci_probe(parent, match, aux)
273 struct device *parent;
274 void *match, *aux;
275 {
276 struct pci_attach_args *pa = aux;
277
278 switch (pa->pa_id) {
279 case PCI_DEVICE_ID_ADAPTEC_398XU:
280 case PCI_DEVICE_ID_ADAPTEC_3940U:
281 case PCI_DEVICE_ID_ADAPTEC_2944U:
282 case PCI_DEVICE_ID_ADAPTEC_2940U:
283 case PCI_DEVICE_ID_ADAPTEC_2940AU:
284 case PCI_DEVICE_ID_ADAPTEC_398X:
285 case PCI_DEVICE_ID_ADAPTEC_3940:
286 case PCI_DEVICE_ID_ADAPTEC_2944:
287 case PCI_DEVICE_ID_ADAPTEC_2940:
288 case PCI_DEVICE_ID_ADAPTEC_AIC7880:
289 case PCI_DEVICE_ID_ADAPTEC_AIC7870:
290 case PCI_DEVICE_ID_ADAPTEC_AIC7860:
291 case PCI_DEVICE_ID_ADAPTEC_AIC7855:
292 case PCI_DEVICE_ID_ADAPTEC_AIC7850:
293 case PCI_DEVICE_ID_ADAPTEC_AIC7810:
294 return 1;
295 }
296 return 0;
297 }
298 #endif /* defined(__NetBSD__) */
299
300 #if defined(__FreeBSD__)
301 static void
302 aic7870_attach(config_id, unit)
303 pcici_t config_id;
304 int unit;
305 #elif defined(__NetBSD__)
306 void
307 ahc_pci_attach(parent, self, aux)
308 struct device *parent, *self;
309 void *aux;
310 #endif
311 {
312 #if defined(__FreeBSD__)
313 u_int16_t io_port;
314 struct ahc_softc *ahc;
315 #elif defined(__NetBSD__)
316 struct pci_attach_args *pa = aux;
317 struct ahc_softc *ahc = (void *)self;
318 int unit = ahc->sc_dev.dv_unit;
319 bus_io_addr_t iobase;
320 bus_io_size_t iosize;
321 bus_io_handle_t ioh;
322 pci_intr_handle_t ih;
323 const char *intrstr;
324 #endif
325 u_int32_t id;
326 u_int32_t command;
327 struct scb_data *shared_scb_data;
328 int opri;
329 ahc_type ahc_t = AHC_NONE;
330 ahc_flag ahc_f = AHC_FNONE;
331 vm_offset_t vaddr;
332 vm_offset_t paddr;
333 u_int8_t ultra_enb = 0;
334 u_int8_t our_id = 0;
335 u_int8_t sxfrctl1;
336
337 shared_scb_data = NULL;
338 vaddr = NULL;
339 paddr = NULL;
340 #if defined(__FreeBSD__)
341 io_port = 0;
342 command = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG);
343 #ifdef AHC_ALLOW_MEMIO
344 if ((command & PCI_COMMAND_MEM_ENABLE) == 0
345 || (pci_map_mem(config_id, PCI_BASEADR1, &vaddr, &paddr)) == 0)
346 #endif
347 if ((command & PCI_COMMAND_IO_ENABLE) == 0
348 || (pci_map_port(config_id, PCI_BASEADR0, &io_port)) == 0)
349 return;
350 #elif defined(__NetBSD__)
351 /* XXX Memory mapped I/O?? */
352 if (bus_io_map(pa->pa_bc, iobase, iosize, &ioh))
353 if (pci_io_find(pa->pa_pc, pa->pa_tag, PCI_BASEADR0, &iobase,
354 &iosize))
355 return;
356 #endif
357
358 #if defined(__FreeBSD__)
359 switch ((id = pci_conf_read(config_id, PCI_ID_REG))) {
360 #elif defined(__NetBSD__)
361 switch (id = pa->pa_id) {
362 #endif
363 case PCI_DEVICE_ID_ADAPTEC_398XU:
364 case PCI_DEVICE_ID_ADAPTEC_398X:
365 if (id == PCI_DEVICE_ID_ADAPTEC_398XU)
366 ahc_t = AHC_398U;
367 else
368 ahc_t = AHC_398;
369 switch (aic398X_count) {
370 case 0:
371 break;
372 case 1:
373 ahc_f |= AHC_CHNLB;
374 break;
375 case 2:
376 ahc_f |= AHC_CHNLC;
377 break;
378 default:
379 break;
380 }
381 aic398X_count++;
382 if (first_398X != NULL)
383 #ifdef AHC_SHARE_SCBS
384 shared_scb_data = first_398X->scb_data;
385 #endif
386 if (aic398X_count == 3) {
387 /*
388 * This is the last device on this RAID
389 * controller, so reset our counts.
390 * XXX This won't work for the multiple 3980
391 * controllers since they have only 2 channels,
392 * but I'm not even sure if Adaptec actually
393 * went through with their plans to produce
394 * this controller.
395 */
396 aic398X_count = 0;
397 first_398X = NULL;
398 }
399 break;
400 case PCI_DEVICE_ID_ADAPTEC_3940U:
401 case PCI_DEVICE_ID_ADAPTEC_3940:
402 if (id == PCI_DEVICE_ID_ADAPTEC_3940U)
403 ahc_t = AHC_394U;
404 else
405 ahc_t = AHC_394;
406 if ((aic3940_count & 0x01) != 0)
407 /* Odd count implies second channel */
408 ahc_f |= AHC_CHNLB;
409 aic3940_count++;
410 break;
411 case PCI_DEVICE_ID_ADAPTEC_2944U:
412 case PCI_DEVICE_ID_ADAPTEC_2940U:
413 ahc_t = AHC_294U;
414 break;
415 case PCI_DEVICE_ID_ADAPTEC_2944:
416 case PCI_DEVICE_ID_ADAPTEC_2940:
417 ahc_t = AHC_294;
418 break;
419 case PCI_DEVICE_ID_ADAPTEC_2940AU:
420 ahc_t = AHC_294AU;
421 break;
422 case PCI_DEVICE_ID_ADAPTEC_AIC7880:
423 ahc_t = AHC_AIC7880;
424 break;
425 case PCI_DEVICE_ID_ADAPTEC_AIC7870:
426 ahc_t = AHC_AIC7870;
427 break;
428 case PCI_DEVICE_ID_ADAPTEC_AIC7860:
429 ahc_t = AHC_AIC7860;
430 break;
431 case PCI_DEVICE_ID_ADAPTEC_AIC7855:
432 case PCI_DEVICE_ID_ADAPTEC_AIC7850:
433 ahc_t = AHC_AIC7850;
434 break;
435 case PCI_DEVICE_ID_ADAPTEC_AIC7810:
436 printf("RAID functionality unsupported\n");
437 return;
438 default:
439 break;
440 }
441
442 /* On all PCI adapters, we allow SCB paging */
443 ahc_f |= AHC_PAGESCBS;
444 #if defined(__FreeBSD__)
445 if ((ahc = ahc_alloc(unit, io_port, vaddr, ahc_t, ahc_f,
446 shared_scb_data)) == NULL)
447 return; /* XXX PCI code should take return status */
448 #else
449 ahc_construct(ahc, pa->pa_bc, ioh, ahc_t, ahc_f);
450 #endif
451
452 /* Remeber how the card was setup in case there is no SEEPROM */
453 our_id = ahc_inb(ahc, SCSIID) & OID;
454 if (ahc_t & AHC_ULTRA)
455 ultra_enb = ahc_inb(ahc, SXFRCTL0) & FAST20;
456 sxfrctl1 = ahc_inb(ahc, SXFRCTL1) & STPWEN;
457
458 #if defined(__NetBSD__)
459 printf("\n");
460 #endif
461 ahc_reset(ahc);
462
463 #ifdef AHC_SHARE_SCBS
464 if (ahc_t & AHC_AIC7870) {
465 #if defined(__FreeBSD__)
466 u_int32_t devconfig = pci_conf_read(config_id, DEVCONFIG);
467 #elif defined(__NetBSD__)
468 u_int32_t devconfig =
469 pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
470 #endif
471 if (devconfig & (RAMPSM)) {
472 /* XXX Assume 9bit SRAM and enable parity checking */
473 devconfig |= EXTSCBPEN;
474
475 /* XXX Assume fast SRAM and only enable 2 cycle
476 * access if we are sharing the SRAM across mutiple
477 * adapters (398X adapter).
478 */
479 if ((devconfig & MPORTMODE) == 0)
480 /* Multi-user mode */
481 devconfig |= EXTSCBTIME;
482
483 devconfig &= ~SCBRAMSEL;
484 #if defined(__FreeBSD__)
485 pci_conf_write(config_id, DEVCONFIG, devconfig);
486 #elif defined(__NetBSD__)
487 pci_conf_write(pa->pa_pc, pa->pa_tag,
488 DEVCONFIG, devconfig);
489 #endif
490 }
491 }
492 #endif
493
494 #if defined(__FreeBSD__)
495 if (!(pci_map_int(config_id, ahc_intr, (void *)ahc, &bio_imask))) {
496 ahc_free(ahc);
497 return;
498 }
499 #elif defined(__NetBSD__)
500
501 if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
502 pa->pa_intrline, &ih)) {
503 printf("%s: couldn't map interrupt\n", ahc->sc_dev.dv_xname);
504 ahc_free(ahc);
505 return;
506 }
507 intrstr = pci_intr_string(pa->pa_pc, ih);
508 #ifdef __OpenBSD__
509 ahc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ahc_intr, ahc,
510 ahc->sc_dev.dv_xname);
511 #else
512 ahc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ahc_intr, ahc);
513 #endif
514 if (ahc->sc_ih == NULL) {
515 printf("%s: couldn't establish interrupt",
516 ahc->sc_dev.dv_xname);
517 if (intrstr != NULL)
518 printf(" at %s", intrstr);
519 printf("\n");
520 ahc_free(ahc);
521 return;
522 }
523 if (intrstr != NULL)
524 printf("%s: interrupting at %s\n", ahc->sc_dev.dv_xname,
525 intrstr);
526 #endif
527 /*
528 * Protect ourself from spurrious interrupts during
529 * intialization.
530 */
531 opri = splbio();
532
533 /*
534 * Do aic7880/aic7870/aic7860/aic7850 specific initialization
535 */
536 {
537 u_int8_t sblkctl;
538 char *id_string;
539
540 switch(ahc->type) {
541 case AHC_398U:
542 case AHC_394U:
543 case AHC_294U:
544 case AHC_AIC7880:
545 id_string = "aic7880 ";
546 load_seeprom(ahc, &sxfrctl1);
547 break;
548 case AHC_398:
549 case AHC_394:
550 case AHC_294:
551 case AHC_AIC7870:
552 id_string = "aic7870 ";
553 load_seeprom(ahc, &sxfrctl1);
554 break;
555 case AHC_294AU:
556 case AHC_AIC7860:
557 id_string = "aic7860 ";
558 load_seeprom(ahc, &sxfrctl1);
559 break;
560 case AHC_AIC7850:
561 id_string = "aic7850 ";
562 /*
563 * Use defaults, if the chip wasn't initialized by
564 * a BIOS.
565 */
566 ahc->flags |= AHC_USEDEFAULTS;
567 break;
568 default:
569 printf("ahc: Unknown controller type. Ignoring.\n");
570 ahc_free(ahc);
571 splx(opri);
572 return;
573 }
574
575 /*
576 * Take the LED out of diagnostic mode
577 */
578 sblkctl = ahc_inb(ahc, SBLKCTL);
579 ahc_outb(ahc, SBLKCTL, (sblkctl & ~(DIAGLEDEN|DIAGLEDON)));
580
581 /*
582 * I don't know where this is set in the SEEPROM or by the
583 * BIOS, so we default to 100%.
584 */
585 ahc_outb(ahc, DSPCISTATUS, DFTHRSH_100);
586
587 if (ahc->flags & AHC_USEDEFAULTS) {
588 /*
589 * PCI Adapter default setup
590 * Should only be used if the adapter does not have
591 * an SEEPROM.
592 */
593 /* See if someone else set us up already */
594 u_int32_t i;
595 for (i = TARG_SCRATCH; i < 0x60; i++) {
596 if (ahc_inb(ahc, i) != 0x00)
597 break;
598 }
599 if (i == TARG_SCRATCH) {
600 /*
601 * Try looking for all ones. You can get
602 * either.
603 */
604 for (i = TARG_SCRATCH; i < 0x60; i++) {
605 if (ahc_inb(ahc, i) != 0xff)
606 break;
607 }
608 }
609 if ((i != 0x60) && (our_id != 0)) {
610 printf("%s: Using left over BIOS settings\n",
611 ahc_name(ahc));
612 ahc->flags &= ~AHC_USEDEFAULTS;
613 } else {
614 /*
615 * Assume only one connector and always turn
616 * on termination.
617 */
618 our_id = 0x07;
619 sxfrctl1 = STPWEN;
620 }
621 ahc_outb(ahc, SCSICONF,
622 (our_id & 0x07)|ENSPCHK|RESET_SCSI);
623 /* In case we are a wide card */
624 ahc_outb(ahc, SCSICONF + 1, our_id);
625
626 if (ultra_enb == 0
627 && (ahc->flags & AHC_USEDEFAULTS) == 0) {
628 /*
629 * If there wasn't a BIOS or the board
630 * wasn't in this mode to begin with,
631 * turn off ultra.
632 */
633 ahc->type &= ~AHC_ULTRA;
634 }
635 }
636
637 printf("%s: %s", ahc_name(ahc), id_string);
638 }
639
640 /*
641 * Put our termination setting into sxfrctl1 now so that the
642 * generic initialization can see it.
643 */
644 sxfrctl1 |= ahc_inb(ahc, SXFRCTL1);
645 ahc_outb(ahc, SXFRCTL1, sxfrctl1);
646
647 if (ahc_init(ahc)){
648 ahc_free(ahc);
649 splx(opri);
650 return; /* XXX PCI code should take return status */
651 }
652
653 if ((ahc->type & AHC_398) == AHC_398) {
654 /* Only set this once we've successfully probed */
655 if (shared_scb_data == NULL)
656 first_398X = ahc;
657 }
658 splx(opri);
659
660 ahc_attach(ahc);
661 }
662
663 /*
664 * Read the SEEPROM. Return 0 on failure
665 */
666 void
667 load_seeprom(ahc, sxfrctl1)
668 struct ahc_softc *ahc;
669 u_int8_t *sxfrctl1;
670 {
671 struct seeprom_descriptor sd;
672 struct seeprom_config sc;
673 u_int16_t *scarray = (u_int16_t *)≻
674 u_int8_t scsi_conf;
675 u_int8_t host_id;
676 int have_seeprom;
677
678 #if defined(__FreeBSD__)
679 sd.sd_maddr = ahc->maddr;
680 if (sd.sd_maddr != NULL)
681 sd.sd_maddr += SEECTL;
682 sd.sd_iobase = ahc->baseport;
683 if (sd.sd_iobase != 0)
684 sd.sd_iobase += SEECTL;
685 #elif defined(__NetBSD__)
686 sd.sd_bc = ahc->sc_bc;
687 sd.sd_ioh = ahc->sc_ioh;
688 sd.sd_offset = SEECTL;
689 #endif
690 /*
691 * For some multi-channel devices, the c46 is simply too
692 * small to work. For the other controller types, we can
693 * get our information from either SEEPROM type. Set the
694 * type to start our probe with accordingly.
695 */
696 if ((ahc->type & AHC_398) == AHC_398)
697 sd.sd_chip = C56_66;
698 else
699 sd.sd_chip = C46;
700 sd.sd_MS = SEEMS;
701 sd.sd_RDY = SEERDY;
702 sd.sd_CS = SEECS;
703 sd.sd_CK = SEECK;
704 sd.sd_DO = SEEDO;
705 sd.sd_DI = SEEDI;
706
707 have_seeprom = acquire_seeprom(&sd);
708 if (have_seeprom) {
709 if (bootverbose)
710 printf("%s: Reading SEEPROM...", ahc_name(ahc));
711
712 for (;;) {
713 u_int start_addr;
714
715 start_addr = ahc->flags & (AHC_CHNLB|AHC_CHNLC);
716
717 have_seeprom = read_seeprom(&sd, (u_int16_t *)&sc,
718 start_addr, sizeof(sc)/2);
719
720 if (have_seeprom) {
721 /* Check checksum */
722 int i;
723 int maxaddr;
724 u_int16_t *scarray;
725 u_int16_t checksum;
726
727 maxaddr = (sizeof(sc)/2) - 1;
728 checksum = 0;
729 scarray = (u_int16_t *)≻
730
731 for (i = 0; i < maxaddr; i++)
732 checksum = checksum + scarray[i];
733 if (checksum == 0 || checksum != sc.checksum) {
734 if (bootverbose && sd.sd_chip == C56_66)
735 printf ("checksum error\n");
736 have_seeprom = 0;
737 } else {
738 if (bootverbose)
739 printf("done.\n");
740 break;
741 }
742 }
743
744 if (sd.sd_chip == C56_66)
745 break;
746 sd.sd_chip = C56_66;
747 }
748 }
749 release_seeprom(&sd);
750 if (!have_seeprom) {
751 if (bootverbose)
752 printf("\n%s: No SEEPROM available\n", ahc_name(ahc));
753 ahc->flags |= AHC_USEDEFAULTS;
754 } else {
755 /*
756 * Put the data we've collected down into SRAM
757 * where ahc_init will find it.
758 */
759 int i;
760 int max_targ = sc.max_targets & CFMAXTARG;
761
762 for (i = 0; i < max_targ; i++){
763 u_char target_settings;
764 target_settings = (sc.device_flags[i] & CFXFER) << 4;
765 if (sc.device_flags[i] & CFSYNCH)
766 target_settings |= SOFS;
767 if (sc.device_flags[i] & CFWIDEB)
768 target_settings |= WIDEXFER;
769 if (sc.device_flags[i] & CFDISC)
770 ahc->discenable |= (0x01 << i);
771 ahc_outb(ahc, TARG_SCRATCH+i, target_settings);
772 }
773 ahc_outb(ahc, DISC_DSB, ~(ahc->discenable & 0xff));
774 ahc_outb(ahc, DISC_DSB + 1, ~((ahc->discenable >> 8) & 0xff));
775
776 host_id = sc.brtime_id & CFSCSIID;
777
778 scsi_conf = (host_id & 0x7);
779 if (sc.adapter_control & CFSPARITY)
780 scsi_conf |= ENSPCHK;
781 if (sc.adapter_control & CFRESETB)
782 scsi_conf |= RESET_SCSI;
783
784 /*
785 * Update the settings in sxfrctl1 to match the
786 *termination settings
787 */
788 *sxfrctl1 = 0;
789 if (sc.adapter_control & CFAUTOTERM) {
790 /* Play around with the memory port */
791 have_seeprom = acquire_seeprom(&sd);
792 if (have_seeprom) {
793 u_int8_t brdctl;
794 u_int8_t seectl;
795 int internal50_present;
796 int internal68_present;
797 int external68_present;
798 int eprom_present;
799 int high_on;
800 int low_on;
801
802 seectl = sd.sd_CS|sd.sd_MS;
803 SEEPROM_OUTB(&sd, seectl);
804 /*
805 * First read the status of our cables.
806 * Set the rom bank to 0 since the
807 * bank setting serves as a multiplexor
808 * for the cable detection logic.
809 * BRDDAT5 controls the bank switch.
810 */
811 write_brdctl(ahc, 0);
812
813 /*
814 * Now read the state of the internal
815 * connectors. BRDDAT6 is INT50 and
816 * BRDDAT7 is INT68.
817 */
818 brdctl = read_brdctl(ahc);
819 internal50_present = !(brdctl & BRDDAT6);
820 internal68_present = !(brdctl & BRDDAT7)
821 && (max_targ > 8);
822 if (bootverbose) {
823 printf("internal50 cable %s present\n"
824 "internal68 cable %s present\n"
825 "brdctl == 0x%x\n",
826 internal50_present ? "is":"not",
827 internal68_present ? "is":"not",
828 brdctl);
829 }
830
831 /*
832 * Set the rom bank to 1 and determine
833 * the other signals.
834 */
835 write_brdctl(ahc, BRDDAT5);
836
837 /*
838 * Now read the state of the external
839 * connectors. BRDDAT6 is EXT68 and
840 * BRDDAT7 is EPROMPS.
841 */
842 brdctl = read_brdctl(ahc);
843 external68_present = !(brdctl & BRDDAT6);
844 eprom_present = brdctl & BRDDAT7;
845 if (bootverbose) {
846 printf("external cable %s present\n"
847 "eprom %s present\n"
848 "brdctl == 0x%x\n",
849 external68_present ? "is":"not",
850 eprom_present ? "is" : "not",
851 brdctl);
852 }
853
854 /*
855 * Now set the termination based on what
856 * we found. BRDDAT6 controls wide
857 * termination enable.
858 */
859 high_on = FALSE;
860 low_on = FALSE;
861 if ((max_targ > 8)
862 && ((external68_present == 0)
863 || (internal68_present == 0)))
864 high_on = TRUE;
865
866 if (((internal50_present ? 1 : 0)
867 + (internal68_present ? 1 : 0)
868 + (external68_present ? 1 : 0)) <= 1)
869 low_on = TRUE;
870
871 if ((internal50_present != 0)
872 && (internal68_present != 0)
873 && (external68_present != 0)) {
874 printf("Illegal cable configuration!!. "
875 "Only two connectors on the "
876 "adapter may be used at a "
877 "time!");
878 }
879
880 if (high_on == TRUE)
881 write_brdctl(ahc, BRDDAT6);
882 else
883 write_brdctl(ahc, 0);
884
885 if (low_on == TRUE)
886 *sxfrctl1 |= STPWEN;
887
888 if (bootverbose) {
889 printf("low byte termination %s, "
890 "high byte termination %s\n",
891 low_on ? "enabled":"disabled",
892 high_on ? "enabled":"disabled");
893 }
894 }
895 release_seeprom(&sd);
896 } else {
897 if (sc.adapter_control & CFSTERM)
898 *sxfrctl1 |= STPWEN;
899 have_seeprom = acquire_seeprom(&sd);
900 if (have_seeprom) {
901 SEEPROM_OUTB(&sd, sd.sd_CS|sd.sd_MS);
902 if (sc.adapter_control & CFWSTERM)
903 write_brdctl(ahc, BRDDAT6);
904 else
905 write_brdctl(ahc, 0);
906 release_seeprom(&sd);
907 } else
908 printf("Unabled to configure high byte "
909 "termination!\n");
910
911 if (bootverbose) {
912 printf("low byte termination %s, "
913 "high byte termination %s\n",
914 sc.adapter_control & CFSTERM ?
915 "enabled":"disabled",
916 sc.adapter_control & CFWSTERM ?
917 "enabled":"disabled");
918 }
919 }
920
921 if (ahc->type & AHC_ULTRA) {
922 /* Should we enable Ultra mode? */
923 if (!(sc.adapter_control & CFULTRAEN))
924 /* Treat us as a non-ultra card */
925 ahc->type &= ~AHC_ULTRA;
926 }
927 /* Set the host ID */
928 ahc_outb(ahc, SCSICONF, scsi_conf);
929 /* In case we are a wide card */
930 ahc_outb(ahc, SCSICONF + 1, host_id);
931 }
932 }
933
934 static int
935 acquire_seeprom(sd)
936 struct seeprom_descriptor *sd;
937 {
938 int wait;
939
940 /*
941 * Request access of the memory port. When access is
942 * granted, SEERDY will go high. We use a 1 second
943 * timeout which should be near 1 second more than
944 * is needed. Reason: after the chip reset, there
945 * should be no contention.
946 */
947 SEEPROM_OUTB(sd, sd->sd_MS);
948 wait = 1000; /* 1 second timeout in msec */
949 while (--wait && ((SEEPROM_INB(sd) & sd->sd_RDY) == 0)) {
950 DELAY (1000); /* delay 1 msec */
951 }
952 if ((SEEPROM_INB(sd) & sd->sd_RDY) == 0) {
953 SEEPROM_OUTB(sd, 0);
954 return (0);
955 }
956 return(1);
957 }
958
959 static void
960 release_seeprom(sd)
961 struct seeprom_descriptor *sd;
962 {
963 /* Release access to the memory port and the serial EEPROM. */
964 SEEPROM_OUTB(sd, 0);
965 }
966
967 static void
968 write_brdctl(ahc, value)
969 struct ahc_softc *ahc;
970 u_int8_t value;
971 {
972 u_int8_t brdctl;
973
974 brdctl = BRDCS|BRDSTB;
975 ahc_outb(ahc, BRDCTL, brdctl);
976 brdctl |= value;
977 ahc_outb(ahc, BRDCTL, brdctl);
978 brdctl &= ~BRDSTB;
979 ahc_outb(ahc, BRDCTL, brdctl);
980 brdctl &= ~BRDCS;
981 ahc_outb(ahc, BRDCTL, brdctl);
982 }
983
984 static u_int8_t
985 read_brdctl(ahc)
986 struct ahc_softc *ahc;
987 {
988 ahc_outb(ahc, BRDCTL, BRDRW|BRDCS);
989 return ahc_inb(ahc, BRDCTL);
990 }
991
992 #endif /* NPCI > 0 */
Cache object: 9baf0feb84adb84ab0fa0e17c93661c4
|