The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/sqtzdc/zdinit.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.