FreeBSD/Linux Kernel Cross Reference
sys/sqtzdc/zdinit.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1991 Carnegie Mellon University
4 * Copyright (c) 1991 Sequent Computer Systems
5 * All Rights Reserved.
6 *
7 * Permission to use, copy, modify and distribute this software and its
8 * documentation is hereby granted, provided that both the copyright
9 * notice and this permission notice appear in all copies of the
10 * software, derivative works or modified versions, and any portions
11 * thereof, and that both notices appear in supporting documentation.
12 *
13 * CARNEGIE MELLON AND SEQUENT COMPUTER SYSTEMS ALLOW FREE USE OF
14 * THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON AND
15 * SEQUENT COMPUTER SYSTEMS DISCLAIM ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 *
18 * Carnegie Mellon requests users of this software to return to
19 *
20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
24 *
25 * any improvements or extensions that they make and grant Carnegie Mellon
26 * the rights to redistribute these changes.
27 */
28
29 /*
30 * HISTORY
31 * $Log: zdinit.c,v $
32 * Revision 2.4 93/03/11 14:06:00 danner
33 * u_long -> u_int
34 * [93/03/10 danner]
35 *
36 * Revision 2.3 91/07/31 18:09:11 dbg
37 * Changed copyright.
38 * [91/07/31 dbg]
39 *
40 * Revision 2.2 91/05/08 13:08:34 dbg
41 * Added volatile declarations.
42 * Allowed interrupts on any CPU.
43 * [91/03/25 dbg]
44 *
45 * Adapted for pure Mach kernel.
46 * [90/10/04 dbg]
47 *
48 */
49
50 #ifndef lint
51 static char rcsid[] = "$Header: zdinit.c,v 2.4 93/03/11 14:06:00 danner Exp $";
52 #endif
53
54 /*
55 * zdinit.c
56 *
57 * Initialization portion ZDC SMD Disk Driver.
58 *
59 * Auto-configure ZDC controllers and drives. Intialize ZDC controllers.
60 * Uses polled interface to communicate with ZDC.
61 */
62
63 /*
64 * Revision 1.2 89/08/16 15:20:57 kak
65 * balance -> sqt
66 *
67 * Revision 1.1 89/07/05 13:21:06 kak
68 * Initial revision
69 *
70 * Revision 1.21 89/01/12 14:22:00 djg
71 * zdcmdtime is now of type unsigned.
72 *
73 * Revision 1.20 88/12/21 10:38:09 djg
74 * fixed lint warnings
75 *
76 * Revision 1.19 88/11/10 08:24:26 djg
77 * bak242 now uses l.cpu_speed
78 *
79 */
80
81 #ifdef MACH_KERNEL
82 #include <sys/types.h>
83
84 #include <device/buf.h>
85 #include <device/param.h>
86
87 #include <sqt/macros.h>
88 #include <sqt/vm_defs.h>
89 #include <sqt/cfg.h>
90 #include <sqt/slic.h>
91 #include <sqt/slicreg.h>
92 #include <sqt/clkarb.h>
93 #include <sqt/mutex.h>
94 #include <sqt/intctl.h>
95
96 #include <sqtzdc/zdc.h>
97 #include <sqtzdc/ioconf.h>
98
99 #define max_RAW_IO (128*1024) /* used for config */
100
101 #else MACH_KERNEL
102 #include "sys/param.h"
103 #include "sys/buf.h"
104 #include "sys/systm.h"
105 #include "sys/time.h"
106 #include "sys/dk.h"
107 #include "sys/vmmeter.h"
108
109 #include "sqt/cfg.h"
110 #include "sqt/slic.h"
111 #include "sqt/slicreg.h"
112 #include "sqt/clkarb.h"
113
114 #include "sqt/mutex.h"
115 #include "sqt/intctl.h"
116 #include "sqt/vmparam.h"
117 #include "sqt/pte.h"
118 #include "sqt/plocal.h"
119
120 #include "sqtzdc/zdc.h"
121 #include "sqtzdc/ioconf.h"
122
123 #ifdef MACH
124 #include "../machine/cpu.h"
125 #include "../sqt/engine.h"
126
127 #define max_RAW_IO (128*1024) /* used for config */
128 #endif
129 #endif MACH_KERNEL
130
131 /*
132 * Kernel Hack to turn off 16 byte writes
133 */
134 #define ENABLE_SIXTEEN 0 /* do not allow 16byte writes */
135 int enable_sixteen = ENABLE_SIXTEEN;
136
137 #define PLURAL(x) ((x) == 1 ? "" : "s")
138 #define CHAN_A 0 /* Channel A */
139 #define CHAN_B 1 /* Channel B */
140 #define ERRLIGHTON { if (fp_lights) FP_IO_ERROR; }
141
142 extern int zdntypes; /* no of known drive types */
143 extern int zdc_iovpercb; /* no of iovecs per cb */
144 extern int zdc_err_bin; /* bin for error interrupts */
145 extern int zdc_cb_bin; /* bin for cb interrupts */
146 extern int zdccmdtime; /* polled command timeout value */
147 extern int zdcinitime; /* init ctrlr timeout value */
148 extern int zdc_C_throttle; /* Throttle count for DMA channel C */
149 extern short zdcretry; /* retry count on errors */
150 extern gate_t zdcgate; /* gate no. for zdc locks/semas */
151 extern u_char zdctrl; /* additional icb_ctrl bits */
152 extern caddr_t zd_compcodes[]; /* completion codes in english */
153 extern int zdncompcodes; /* no. of entries in zd_compcodes */
154
155 struct zdc_ctlr *zdctrlr; /* zdctrlr array - calloc'd */
156 struct zd_unit *zdunit; /* zdunit array - calloc'd */
157 u_char base_cb_intr; /* base interrupt for zdc driver */
158 u_char base_err_intr; /* base controller interrupt */
159 simple_lock_data_t
160 zdcprlock; /* lock for error message sync */
161
162 static struct cb *basecb; /* base cb */
163 static struct zdcdd *chancfg; /* ZDC_GET_CHANCFG */
164
165 struct zdc_driver zd_driver = { "zd" }; /* STUB */
166
167 extern char * calloc();
168
169 /*
170 * conf_zdc()
171 *
172 * Find all ZDCs and fill-in slic addresses in controller structure.
173 */
174 conf_zdc()
175 {
176 register struct ctlr_toc *toc =
177 PHYSTOKV(&va_CD_LOC->c_toc[SLB_ZDCBOARD], struct ctlr_toc *);
178 register struct ctlr_desc *zdcfg =
179 PHYSTOKV(&va_CD_LOC->c_ctlrs[toc->ct_start], struct ctlr_desc *);
180 register int numzdc = toc->ct_count;
181 register struct zdc_ctlr *ctlrp;
182 register int alivezdc;
183 register int diagflag;
184
185 alivezdc = 0;
186 if (numzdc == 0) {
187 printf("No ZDCs.\n");
188 return;
189 }
190 printf("%d ZDC%s; slic", numzdc, PLURAL(numzdc));
191 callocrnd(sizeof(struct zdc_ctlr));
192 zdctrlr = (struct zdc_ctlr *)calloc(numzdc * sizeof(struct zdc_ctlr));
193 for (ctlrp = zdctrlr; ctlrp < &zdctrlr[numzdc]; ctlrp++, zdcfg++) {
194 ctlrp->zdc_slicaddr = zdcfg->cd_slic;
195 diagflag = zdcfg->cd_diag_flag;
196 if (diagflag & (CFG_FAIL|CFG_DECONF)) {
197 ctlrp->zdc_state = ZDC_DEAD;
198 if (diagflag & CFG_FAIL) {
199 ERRLIGHTON;
200 }
201 } else {
202 ctlrp->zdc_state = ZDC_ALIVE;
203 alivezdc++;
204 }
205 printf(" %d", ctlrp->zdc_slicaddr);
206 ctlrp->zdc_diagflag = diagflag;
207 }
208 printf(".\n");
209
210 if (alivezdc < numzdc) {
211 printf("Not using ZDC: slic");
212 for (ctlrp = zdctrlr; ctlrp < &zdctrlr[numzdc]; ctlrp++) {
213 if (ctlrp->zdc_state == ZDC_DEAD)
214 printf(" %d", ctlrp->zdc_slicaddr);
215 }
216 printf(".\n");
217 }
218
219 /*
220 * Allocate ZDC error interrupt vectors.
221 * Must be allocated contiguously across ZDCs.
222 *
223 * Allocate interrupt vectors for CBs.
224 */
225 ivecres(zdc_err_bin, numzdc);
226 ivecres(zdc_cb_bin, numzdc * NCBPERZDC);
227 }
228
229 /*
230 * Find and bind drives to units.
231 * Initialize each controller.
232 */
233 probe_zdc_devices()
234 {
235 register int i;
236 register struct cb *cbp;
237 register struct zdc_ctlr *ctlrp;
238 register struct zdc_dev *zdv;
239 register struct zd_unit *up;
240 int val;
241 int ctrlr, drive;
242 struct zdcdd *dd;
243 int found[ZDC_MAXCTRLR]; /* bit map - found drives */
244 struct cb lcb;
245 int numzdc =
246 PHYSTOKV(&va_CD_LOC->c_toc[SLB_ZDCBOARD], struct ctlr_toc *)
247 ->ct_count;
248 #ifndef MACH
249 extern long max_RAW_IO; /* Max size RAW IO request (bytes) */
250 #endif
251 extern int zdintr(); /* interrupt handler */
252 extern int zdc_error(); /* Error interrupt handler */
253
254 for (i = 0; i < ZDC_MAXCTRLR; i++)
255 found[i] = 0; /* no drives yet */
256 /*
257 * Check to see if controller FW is initialized.
258 * Wait until ZDC is initialized. If error, mark ZDC as ZDC_DEAD.
259 */
260 for (ctlrp = zdctrlr; ctlrp < &zdctrlr[numzdc]; ctlrp++) {
261 if (ctlrp->zdc_state != ZDC_ALIVE)
262 continue;
263 i = calc_delay(zdcinitime);
264 for (;;) {
265 val = rdslave(ctlrp->zdc_slicaddr, SL_Z_STATUS);
266 if ((val & SLB_ZPARERR) != SLB_ZPARERR) {
267 if ((val & ZDC_READY) == ZDC_READY)
268 break;
269 if ((val & ZDC_ERRMASK) == ZDC_SINIT) {
270 /* Still initializing */
271 if (--i)
272 continue;
273 }
274 }
275 /*
276 * Error found
277 */
278 printf("zdc%d: controller failure - SL_Z_STATUS == 0x%x.\n",
279 ctlrp - zdctrlr, val);
280 printf("zdc%d at slic %d Deconfigured.\n",
281 ctlrp - zdctrlr, ctlrp->zdc_slicaddr);
282 ctlrp->zdc_state = ZDC_DEAD;
283 ERRLIGHTON;
284 break;
285 }
286 }
287
288 /*
289 * Set up interrupt vectors
290 */
291 base_err_intr = ivecpeek(zdc_err_bin);
292 for (i = 0; i < numzdc; i++)
293 ivecinit(zdc_err_bin, ivecall((u_char)zdc_err_bin), zdc_error);
294
295 base_cb_intr = ivecpeek(zdc_cb_bin);
296 for (i = 0; i < NCBPERZDC * numzdc; i++)
297 ivecinit(zdc_cb_bin, ivecall((u_char)zdc_cb_bin), zdintr);
298
299 /*
300 * Allocate CBs
301 */
302 callocrnd(sizeof(struct cb));
303 basecb = (struct cb *)calloc(NCBPERZDC * sizeof(struct cb) * numzdc);
304 for (cbp = basecb; cbp < &basecb[NCBPERZDC * numzdc]; cbp++) {
305 cbp->cb_unit = -1;
306 }
307
308 /*
309 * If zdc_iovpercb not set or too big for max_RAW_IO then
310 * set for max_RAW_IO.
311 */
312 if (zdc_iovpercb <= 0 || ((zdc_iovpercb * I386_PGBYTES) > max_RAW_IO))
313 zdc_iovpercb = (max_RAW_IO + (I386_PGBYTES-1)) / I386_PGBYTES;
314
315 /*
316 * Adjust zdc_iovpercb size to safe size.
317 */
318 zdc_iovpercb = roundup(zdc_iovpercb, IOVALIGN / sizeof(u_int *));
319
320 /*
321 * init_lock to prevent error message garble.
322 */
323 init_lock(&zdcprlock, zdcgate);
324
325 /*
326 * Tell each ZDC where its CB array is located.
327 * Done via Bin1 - Bin4 SLIC interrupts, where Bin 1 is the
328 * least significant byte of the CB address and Bin 4 is
329 * the most significant byte.
330 */
331 #define NBPW 4
332 #define NBBY 8
333
334 cbp = basecb;
335 ctlrp = zdctrlr;
336 for (; ctlrp < &zdctrlr[numzdc]; ctlrp++, cbp += NCBPERZDC) {
337 ctlrp->zdc_cbp = cbp;
338 if (ctlrp->zdc_state == ZDC_ALIVE) {
339 unsigned int cbp_pa;
340 cbp_pa = KVTOPHYS(cbp, unsigned int);
341 for (i = 0; i < NBPW; i++)
342 mIntr(ctlrp->zdc_slicaddr, (u_char)i + 1,
343 (u_char)(cbp_pa >> (i * NBBY)));
344 init_lock(&ctlrp->zdc_ctlrlock, zdcgate);
345 }
346 }
347
348 #undef NBBY
349 #undef NBPW
350
351 /*
352 * Probe devices on ZDC via ZDC_PROBE and ZDC_GET_CHANCFG.
353 * Store results in controller structure.
354 */
355 callocrnd(sizeof(struct zdcdd));
356 chancfg = (struct zdcdd *)calloc(sizeof(struct zdcdd));
357 cbp = &lcb;
358 for (ctlrp = zdctrlr; ctlrp < &zdctrlr[numzdc]; ctlrp++) {
359 if (ctlrp->zdc_state != ZDC_ALIVE)
360 continue;
361 cbp->cb_cmd = ZDC_PROBEDRIVE;
362 if (pollzdcmd(ctlrp, cbp, CHAN_A) < 0) {
363 printf("zdc%d: Cannot probe zdc.\n", ctlrp - zdctrlr);
364 printf("zdc%d at slic %d Deconfigured.\n",
365 ctlrp - zdctrlr, ctlrp->zdc_slicaddr);
366 ctlrp->zdc_state = ZDC_DEAD;
367 ERRLIGHTON;
368 continue;
369 }
370 for (i = 0; i < ZDC_MAXDRIVES; i++)
371 ctlrp->zdc_drivecfg[i] =
372 ((struct probe_cb *)cbp)->pcb_drivecfg[i];
373
374 if (get_chancfg(ctlrp, CHAN_A) < 0)
375 continue;
376 if (get_chancfg(ctlrp, CHAN_B) < 0)
377 continue;
378 }
379
380 /*
381 * Now set up units resolving any wildcarding.
382 * Report wildcard binding.
383 */
384 callocrnd(sizeof(struct zd_unit));
385 zdunit = (struct zd_unit *)calloc(zdc_conf->zc_nent * sizeof(struct zd_unit));
386 up = zdunit;
387 for (zdv=zdc_conf->zc_dev; zdv < &zdc_zd[zdc_conf->zc_nent]; zdv++, up++) {
388 up->zu_state = ZU_NOTFOUND;
389 /*
390 * First bind to controller.
391 */
392 for (ctrlr = 0; ctrlr < numzdc; ctrlr++) {
393 if (ctrlr != zdv->zdv_idx && zdv->zdv_idx != ANY)
394 continue;
395 ctlrp = &zdctrlr[ctrlr];
396 if (ctlrp->zdc_state != ZDC_ALIVE && zdv->zdv_idx == ANY)
397 continue;
398 /*
399 * Controller matched.
400 */
401 up->zu_ctrlr = ctrlr;
402 if (ctlrp->zdc_state != ZDC_ALIVE) {
403 printf("zd%d on dead controller zdc%d.\n",
404 up - zdunit, ctrlr);
405 up->zu_state = ZU_BAD;
406 disk_offline();
407 break; /* next unit */
408 }
409 /*
410 * Now bind drive.
411 */
412 for (drive = 0; drive < ZDC_MAXDRIVES; drive++) {
413 if (drive != zdv->zdv_drive &&
414 zdv->zdv_drive != ANY)
415 continue;
416 if (found[ctrlr] & (1 << drive)) {
417 /*
418 * Already bound to another unit
419 */
420 continue;
421 }
422 if (ctlrp->zdc_drivecfg[drive] == ZD_NOTFOUND) {
423 /*
424 * If drive not found and wildcarding
425 * drive, then continue search on this
426 * ZDC. If drive not found and bound
427 * drive but wildcarding ZDC, continue
428 * search on another controller.
429 */
430 if (zdv->zdv_drive == ANY)
431 continue;
432 if (zdv->zdv_idx == ANY)
433 break;
434 /* No - use this drive */
435 }
436 dd = (drive & 1) ? &ctlrp->zdc_chanB
437 : &ctlrp->zdc_chanA;
438 if (zdv->zdv_drive_type != ANY
439 && (dd->zdd_sectors == 0 ||
440 zdv->zdv_drive_type != dd->zdd_drive_type)) {
441 /*
442 * If type doesn't match configured and
443 * drive wildcarded, then continue
444 * search on this ZDC.
445 * If type doesn't match configured but
446 * bound drive and ZDC wildcarded,
447 * continue search on another ZDC.
448 */
449 if (zdv->zdv_drive == ANY)
450 continue;
451 if (zdv->zdv_idx == ANY)
452 break;
453 /* Else, bound to this drive */
454 }
455
456 /*
457 * Drive Matched.
458 */
459 found[ctrlr] |= 1 << drive;
460 printf("zd%d bound to zdc%d drive %d.\n",
461 up - zdunit, ctrlr, drive);
462 up->zu_drive = drive;
463 if (dd->zdd_sectors == 0
464 || (zdv->zdv_drive_type != ANY &&
465 zdv->zdv_drive_type != dd->zdd_drive_type)
466 || (dd->zdd_drive_type >= zdntypes)) {
467 /*
468 * If no channel cfg or drive doesn't
469 * match configuration, set state to
470 * ZU_NO_RW. Since zdsize() will be
471 * called before open, the size routine
472 * will not allow swap I/O to drives
473 * that mismatch the configuration.
474 */
475 up->zu_drive_type = zdv->zdv_drive_type;
476 up->zu_state = ZU_NO_RW;
477 } else {
478 /*
479 * OK match set drive type.
480 */
481 up->zu_drive_type = dd->zdd_drive_type;
482 up->zu_state = ZU_GOOD;
483 }
484 up->zu_cfg = ctlrp->zdc_drivecfg[drive];
485 up->zu_zdbad = NULL;
486 #ifndef MACH
487 bufinit(&up->zu_ioctl, zdcgate);
488 #endif MACH
489 init_lock(&up->zu_lock, zdcgate);
490 init_sema(&up->zu_ocsema, 1, 0, zdcgate);
491 #ifndef MACH
492 if (dk_nxdrive < dk_ndrives) {
493 /*
494 * Set up dk style statistics.
495 * Note: that dk_bps is NOT kept.
496 * It is set non-zero so that iostat
497 * will still report other useful stats
498 * for the drive.
499 */
500 up->zu_dkstats = &dk[dk_nxdrive++];
501 up->zu_dkstats->dk_bps = 1; /* FAKE */
502 bcopy("zdXX", up->zu_dkstats->dk_name, 5);
503 i = up - zdunit;
504 if (i > 9) {
505 up->zu_dkstats->dk_name[2] = i/10 + '';
506 i -= (i/10) * 10;
507 up->zu_dkstats->dk_name[3] = i + '';
508 } else {
509 up->zu_dkstats->dk_name[2] = i + '';
510 up->zu_dkstats->dk_name[3] = '\0';
511 }
512 } else {
513 up->zu_dkstats = (struct dk *)NULL;
514 }
515 #endif MACH
516 /*
517 * Set up software cb fields for this unit.
518 */
519 cbp = &ctlrp->zdc_cbp[drive * NCBPERDRIVE];
520 up->zu_cbptr = cbp;
521 cbp->cb_unit = up - zdunit;
522 callocrnd(IOVALIGN);
523 cbp->cb_iovstart =
524 (u_int *)calloc(zdc_iovpercb
525 * sizeof(u_int *));
526 ++cbp;
527 cbp->cb_unit = up - zdunit;
528 cbp->cb_iovstart =
529 (u_int *)calloc(zdc_iovpercb
530 * sizeof(u_int *));
531
532 if (up->zu_cfg == ZD_NOTFOUND ||
533 (up->zu_cfg & ZD_ONLINE) != ZD_ONLINE) {
534 /*
535 * Even though drive not present, the
536 * unit is bound to the drive. It
537 * could be that the drive is not
538 * spun up and will be later...
539 */
540 printf("zd%d: drive not present.\n",
541 up - zdunit);
542 disk_offline();
543 }
544 goto nextunit;
545 } /* drives */
546 } /* ctrlrs */
547
548 /*
549 * If unit not found fill out unit for post-mortem/debug.
550 */
551 if (up->zu_state == ZU_NOTFOUND) {
552 up->zu_ctrlr = zdv->zdv_idx;
553 up->zu_drive = zdv->zdv_drive;
554 up->zu_drive_type = zdv->zdv_drive_type;
555 }
556 nextunit:; /* the ";" necessary to workaround compiler bug */
557 } /* units */
558
559 /*
560 * Send ZDC_INIT command to all alive ZDCs.
561 */
562 init_zdcs(numzdc);
563 }
564
565 /*
566 * a null function.
567 * zdc configuration doesn't need it, but config(1) requires it.
568 */
569 zdc_map() {}
570
571 /*
572 * get_chancfg
573 * get channel configuration.
574 * Return:
575 * 0 - If command completes successfully. The controller structure
576 * is filled with the channel configuration data.
577 * -1 - If error processing ZDC_GET_CHANCFG.
578 *
579 */
580 int
581 get_chancfg(ctlrp, channel)
582 register struct zdc_ctlr *ctlrp;
583 int channel;
584 {
585 register struct cb *cbp;
586 struct cb lcb;
587
588 cbp = &lcb;
589 bzero((caddr_t)cbp, sizeof(struct cb));
590 cbp->cb_cmd = ZDC_GET_CHANCFG; /* command */
591 cbp->cb_addr = KVTOPHYS(chancfg, u_int); /* where to put it */
592 cbp->cb_count = sizeof(struct zdcdd);
593 if (pollzdcmd(ctlrp, cbp, channel) < 0) {
594 printf("zdc%d: Cannot get channel cfg.\n", ctlrp - zdctrlr);
595 printf("zdc%d at slic %d Deconfigured.\n",
596 ctlrp - zdctrlr, ctlrp->zdc_slicaddr);
597 ctlrp->zdc_state = ZDC_DEAD;
598 ERRLIGHTON;
599 return (-1);
600 }
601 if (cbp->cb_compcode == ZDC_NOCFG)
602 return (0);
603
604 if (channel == CHAN_A)
605 ctlrp->zdc_chanA = *chancfg;
606 else
607 ctlrp->zdc_chanB = *chancfg;
608 return (0);
609 }
610
611 /*
612 * bad_zdc
613 * - mark all units on dead zdc as unusable.
614 * Called only during configuration/initialization.
615 */
616 static
617 bad_zdc(ctlr)
618 register int ctlr;
619 {
620 register struct zd_unit *up;
621 register int any;
622
623 printf("zdc%d at slic %d Deconfigured.\n", ctlr,
624 zdctrlr[ctlr].zdc_slicaddr);
625 any = 0;
626 for (up = zdunit; up < &zdunit[zdc_conf->zc_nent]; up++) {
627 if (up->zu_ctrlr == ctlr && up->zu_state == ZU_GOOD) {
628 ++any;
629 up->zu_state = ZU_BAD; /* on dead ctrlr */
630 disk_offline();
631 printf("zd%d, ", up - zdunit);
632 }
633 }
634 if (any)
635 printf("%s unusable.\n", (any == 1) ? "is" : "are");
636 }
637
638 /*
639 * init_zdc
640 * init all zdc controllers via ZDC_INIT command
641 * Initialize interrupts. On successive commands, the ZDC will
642 * generate interrupts to signal command completion.
643 */
644 init_zdcs(numzdc)
645 int numzdc;
646 {
647 register struct init_cb *icbp;
648 register struct zdc_ctlr *ctlrp;
649 u_char cbvec, errvec;
650 struct init_cb lcb;
651
652 icbp = &lcb;
653 bzero((caddr_t)icbp, sizeof(struct init_cb));
654 if (zdc_C_throttle > SLB_TVAL)
655 zdc_C_throttle = SLB_TVAL; /* Set to MAX */
656
657 ctlrp = zdctrlr;
658 errvec = base_err_intr;
659 cbvec = base_cb_intr;
660 for (; ctlrp < &zdctrlr[numzdc]; ctlrp++, errvec++, cbvec += NCBPERZDC){
661 extern int mono_P_slic;
662
663 if (ctlrp->zdc_state != ZDC_ALIVE)
664 continue;
665
666 icbp->icb_cmd = ZDC_INIT;
667 icbp->icb_pagesize = I386_PGBYTES;
668 icbp->icb_dest = SL_GROUP | TMPOS_GROUP;
669 icbp->icb_bin = zdc_cb_bin;
670 icbp->icb_vecbase = cbvec;
671 icbp->icb_errdest = SL_GROUP | TMPOS_GROUP;
672 icbp->icb_errbin = zdc_err_bin;
673 icbp->icb_errvector = errvec;
674 icbp->icb_ctrl = ZDC_ENABLE_INTR;
675 icbp->icb_ctrl |= zdctrl;
676 /*
677 * Enable 16 byte transfers if the bus mode is one of
678 * the BUS_EXTENDED bus modes. Do this after above
679 * "or" of configurable so it can't accidently turn on
680 * 16 byte mode when illegal
681 */
682 if (va_CD_LOC->c_sys_mode.sm_bus_mode == CD_BUS_EXTENDED_NARR ||
683 va_CD_LOC->c_sys_mode.sm_bus_mode == CD_BUS_EXTENDED_WIDE &&
684 enable_sixteen)
685 icbp->icb_ctrl |= ZDC_SIXTEEN;
686 else
687 icbp->icb_ctrl &= ~ZDC_SIXTEEN;
688
689 if (zdctrl & ZDC_DUMPONPANIC) {
690 /*
691 * Give FW a place to dump its LRAM.
692 */
693 callocrnd(I386_PGBYTES); /* align at 1K boundary */
694 ctlrp->zdc_dumpaddr = calloc(ZDC_LRAMSZ);
695 icbp->icb_dumpaddr =
696 KVTOPHYS(ctlrp->zdc_dumpaddr, caddr_t);
697 }
698 if (pollzdcmd(ctlrp, (struct cb *)icbp, CHAN_A) < 0) {
699 printf("zdc%d: Cannot init zdc.\n", ctlrp - zdctrlr);
700 ctlrp->zdc_state = ZDC_DEAD;
701 ERRLIGHTON;
702 /* Mark all units on this controller as BAD */
703 bad_zdc(ctlrp - zdctrlr);
704 }
705 /*
706 * Set throttle value for DMA channel C.
707 */
708 wrslave(ctlrp->zdc_slicaddr, SL_G_CHAN2,
709 (u_char)(SLB_TH_ENB | zdc_C_throttle));
710 }
711 }
712
713 /*
714 * pollzdcmd
715 *
716 * Issue a command to the ZDC.
717 * Poll for completion.
718 * Retry, when necessary.
719 *
720 * Return: transfer count
721 * 0 - Success
722 * -1 - error.
723 * NOTE: If controller error ctlrp->zdc_state is set to ZDC_DEAD.
724 * The caller may choose to set ctlrp->zdc_state to ZDC_DEAD
725 * upon error whether or not the error was a controller error.
726 */
727 int
728 pollzdcmd(ctlrp, acbp, drive)
729 register struct zdc_ctlr *ctlrp;
730 struct cb *acbp;
731 register int drive;
732 {
733 register struct cb *cbp;
734 register int i;
735 register int val;
736 struct cb lcb; /* ZDC_RESET during retries */
737
738 cbp = &ctlrp->zdc_cbp[drive * NCBPERDRIVE];
739 acbp->cb_errcnt = 0;
740
741 retry:
742 /*
743 * Fill in appropriate CB
744 */
745 bcopy((caddr_t)acbp, (caddr_t)cbp, FWCBSIZE);
746
747 /*
748 * Signal ZDC to do command. Poll until completion or timeout.
749 */
750 cbp->cb_compcode = ZDC_BUSY;
751 mIntr(ctlrp->zdc_slicaddr, CBBIN, (u_char)(drive * NCBPERDRIVE));
752
753 i = calc_delay(zdccmdtime);
754 while (*(volatile u_char *)&cbp->cb_compcode == ZDC_BUSY) {
755 if (--i == 0) {
756 /*
757 * Timed out - check for controller error
758 */
759 printf("zdc%d: Cmd %x timeout.\n", ctlrp - zdctrlr,
760 cbp->cb_cmd);
761 val = rdslave(ctlrp->zdc_slicaddr, SL_Z_STATUS);
762 if ((val & SLB_ZPARERR) ||
763 ((val & ZDC_READY) != ZDC_READY)) {
764 /*
765 * Found controller error.
766 */
767 printf("zdc%d: Ctrlr error status 0x%x.\n",
768 ctlrp - zdctrlr, val);
769 /*
770 * controller bad!
771 */
772 ctlrp->zdc_state = ZDC_DEAD;
773 }
774 return (-1);
775 }
776 }
777
778 switch (cbp->cb_compcode) {
779
780 case ZDC_SOFTECC:
781 case ZDC_CORRECC:
782 /*
783 * Corrected or Soft ECC error.
784 */
785 printf("zd%d: %s at (%d, %d, %d).\n",
786 cbp->cb_unit,
787 zd_compcodes[cbp->cb_compcode],
788 cbp->cb_cyl, cbp->cb_head, cbp->cb_sect);
789 zddumpstatus(cbp);
790 /* Fall into... */
791 case ZDC_DONE:
792 /*
793 * Normal completion
794 */
795 *acbp = *cbp;
796 return (0);
797
798 case ZDC_DRVPROT:
799 case ZDC_ECC:
800 case ZDC_BADDRV:
801 case ZDC_DDC_STAT:
802 goto hard;
803
804 case ZDC_DMA_TO:
805 case ZDC_REVECT:
806 case ZDC_ILLCMD:
807 case ZDC_ILLMOD:
808 case ZDC_ILLALIGN:
809 case ZDC_ILLCNT:
810 case ZDC_ILLIOV:
811 case ZDC_ILLVECIO:
812 case ZDC_ILLPGSZ:
813 case ZDC_ILLDUMPADR:
814 case ZDC_ILLCHS:
815 case ZDC_CBREUSE:
816 /*
817 * Hard error. This set indicates controller error.
818 */
819 ctlrp->zdc_state = ZDC_DEAD;
820 goto hard;
821
822 case ZDC_CH_RESET:
823 /*
824 * Drive has failed in the middle of the command!
825 */
826 printf("zd%d: Drive failed during cmd 0x%x.\n",
827 cbp->cb_unit, cbp->cb_cmd);
828 goto hard;
829
830 case ZDC_ACCERR:
831 /*
832 * Most likely controller problem.
833 * Clear access error and notify firmware.
834 */
835 val = rdslave(ctlrp->zdc_slicaddr,
836 (u_char)((drive & 1) ? SL_G_ACCERR1
837 : SL_G_ACCERR0));
838 printf("zd%d: Access error 0x%x on transfer at 0x%x.\n",
839 drive, val, cbp->cb_addr);
840 wrslave(ctlrp->zdc_slicaddr,
841 (u_char)((drive & 1) ? SL_G_ACCERR1 : SL_G_ACCERR0),
842 (u_char)0xbb);
843 ctlrp->zdc_state = ZDC_DEAD;
844 goto hard;
845
846 case ZDC_NOCFG:
847 *acbp = *cbp;
848 if (cbp->cb_cmd == ZDC_GET_CHANCFG)
849 return (0);
850 return (-1);
851
852 case ZDC_HDR_ECC:
853 case ZDC_SNF:
854 case ZDC_SO:
855 case ZDC_NDS:
856 case ZDC_DRVFLT:
857 case ZDC_SEEKERR:
858 case ZDC_SEEK_TO:
859 case ZDC_CH_TO:
860 case ZDC_FDL:
861 /*
862 * Retry these errors.
863 */
864 break;
865
866 default:
867 /*
868 * Unknown completion code - controller bad?
869 */
870 printf("zdc%d: Bad compcode 0x%x.\n", ctlrp - zdctrlr,
871 cbp->cb_compcode);
872 cbp->cb_compcode = zdncompcodes - 1; /* Get nice message */
873 ctlrp->zdc_state = ZDC_DEAD;
874 goto hard;
875 }
876
877 if (cbp->cb_cmd == ZDC_RESET)
878 return (-1);
879
880 printf("zd%d: Error (%s); cmd = 0x%x at (%d, %d, %d).\n",
881 cbp->cb_unit, zd_compcodes[cbp->cb_compcode], cbp->cb_cmd,
882 cbp->cb_cyl, cbp->cb_head, cbp->cb_sect);
883 zddumpstatus(cbp);
884 /*
885 * Retry. Reset the drive each time.
886 */
887 if (acbp->cb_errcnt++ < zdcretry) {
888 lcb.cb_cmd = ZDC_RESET;
889 if (pollzdcmd(ctlrp, &lcb, drive) < 0) {
890 printf("zd%d: RESET failed.\n", cbp->cb_unit);
891 goto hard;
892 }
893 goto retry;
894 } else {
895 /*
896 * save cb contents to return.
897 */
898 *acbp = *cbp;
899 lcb.cb_cmd = ZDC_RESET;
900 if (pollzdcmd(ctlrp, &lcb, drive) < 0)
901 printf("zd%d: RESET failed.\n", cbp->cb_unit);
902 bcopy((caddr_t)acbp, (caddr_t)cbp, FWCBSIZE);
903 }
904
905 hard:
906 /*
907 * Update argument cb and return
908 */
909 printf("zd%d: Hard error (%s); cmd = 0x%x at (%d, %d, %d).\n",
910 cbp->cb_unit, zd_compcodes[cbp->cb_compcode], cbp->cb_cmd,
911 cbp->cb_cyl, cbp->cb_head, cbp->cb_sect);
912 zddumpstatus(cbp);
913 *acbp = *cbp;
914 return (-1);
915 }
Cache object: ee107ff61458ab2a718d4affffa10ebc
|