134293Skarels /* 235041Sbostic * Copyright (c) 1988 Regents of the University of California. 335041Sbostic * All rights reserved. 434293Skarels * 535041Sbostic * This code is derived from software contributed to Berkeley by 635041Sbostic * Chris Torek. 735041Sbostic * 835041Sbostic * Redistribution and use in source and binary forms are permitted 935041Sbostic * provided that the above copyright notice and this paragraph are 1035041Sbostic * duplicated in all such forms and that any documentation, 1135041Sbostic * advertising materials, and other materials related to such 1235041Sbostic * distribution and use acknowledge that the software was developed 1335041Sbostic * by the University of California, Berkeley. The name of the 1435041Sbostic * University may not be used to endorse or promote products derived 1535041Sbostic * from this software without specific prior written permission. 1635041Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1735041Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1835041Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1935041Sbostic * 20*38171Smckusick * @(#)kdb.c 7.7 (Berkeley) 05/29/89 2135041Sbostic */ 2235041Sbostic 2335041Sbostic /* 2434293Skarels * KDB50/MSCP device driver 2534293Skarels */ 2634293Skarels 2734293Skarels /* 2834293Skarels * TODO 2934293Skarels * rethink BI software interface 3034293Skarels * write bad block forwarding code 3134293Skarels */ 3234293Skarels 3334293Skarels #include "kra.h" /* XXX */ 3434293Skarels 3534293Skarels #define DRIVENAMES "kra" /* XXX */ 3634293Skarels 3734293Skarels #if NKDB > 0 3834293Skarels 3934293Skarels /* 4034293Skarels * CONFIGURATION OPTIONS. The next three defines are tunable -- tune away! 4134293Skarels * 4234293Skarels * NRSPL2 and NCMDL2 control the number of response and command 4334293Skarels * packets respectively. They may be any value from 0 to 7, though 4434293Skarels * setting them higher than 5 is unlikely to be of any value. 4534293Skarels * If you get warnings about your command ring being too small, 4634293Skarels * try increasing the values by one. 4734293Skarels * 4834293Skarels * MAXUNIT controls the maximum slave number (and hence number of drives 4934293Skarels * per controller) we are prepared to handle. 5034293Skarels */ 5134293Skarels #define NRSPL2 5 /* log2 number of response packets */ 5234293Skarels #define NCMDL2 5 /* log2 number of command packets */ 5334293Skarels #define MAXUNIT 8 /* maximum allowed unit number */ 5434293Skarels 5534293Skarels #include "param.h" 5634293Skarels #include "systm.h" 5734293Skarels #include "malloc.h" 5834293Skarels #include "map.h" 5934293Skarels #include "buf.h" 6034293Skarels #include "conf.h" 6134293Skarels #include "dir.h" 6234293Skarels #include "user.h" 6334293Skarels #include "proc.h" 6434293Skarels #include "vm.h" 6534293Skarels #include "dkstat.h" 6634293Skarels #include "cmap.h" 6734293Skarels #include "syslog.h" 6834293Skarels #include "kernel.h" 6934293Skarels 7034293Skarels #define NRSP (1 << NRSPL2) 7134293Skarels #define NCMD (1 << NCMDL2) 7234293Skarels 7334510Skarels #include "../vax/pte.h" 7434293Skarels #include "../vax/cpu.h" 7534293Skarels #include "../vax/mscp.h" 7634293Skarels #include "../vax/mscpvar.h" 7734293Skarels #include "../vax/mtpr.h" 7834293Skarels 7934293Skarels #include "bireg.h" 8034293Skarels #include "kdbreg.h" 8134510Skarels 8234293Skarels #include "../vaxuba/ubavar.h" 8334293Skarels 8434293Skarels /* 8534293Skarels * Conversions from kernel virtual to physical and page table addresses. 8634293Skarels * PHYS works only for kernel text and primary (compile time) data addresses. 8734293Skarels */ 8834293Skarels #define PHYS(cast, addr) \ 8934293Skarels ((cast) ((int)(addr) & 0x7fffffff)) 9034293Skarels 9134293Skarels /* 9234293Skarels * KDB variables, per controller. 9334293Skarels */ 9434293Skarels struct kdbinfo { 9534293Skarels /* software info, per KDB */ 9634293Skarels struct kdb_regs *ki_kdb; /* KDB registers */ 9734293Skarels struct kdb_regs *ki_physkdb; /* phys address of KDB registers */ 9834293Skarels short ki_state; /* KDB50 state; see below */ 9934293Skarels short ki_flags; /* flags; see below */ 10034293Skarels int ki_micro; /* microcode revision */ 10134293Skarels short ki_vec; /* scb vector offset */ 10234293Skarels short ki_wticks; /* watchdog timer ticks */ 10334293Skarels 10434293Skarels /* 10534293Skarels * KDB PTEs must be contiguous. Some I/O is done on addresses 10634293Skarels * for which this is true (PTEs in Sysmap and Usrptmap), but 10734293Skarels * other transfers may have PTEs that are scattered in physical 10834293Skarels * space. Ki_map maps a physically contiguous PTE space used 10934757Sbostic * for these transfers. 11034293Skarels */ 11134293Skarels #define KI_MAPSIZ (NCMD + 2) 11234293Skarels struct map *ki_map; /* resource map */ 11334293Skarels #define KI_PTES 256 11434757Sbostic struct pte ki_pte[KI_PTES]; /* contiguous PTE space */ 11534293Skarels long ki_ptephys; /* phys address of &ki_pte[0] */ 11634293Skarels 11734293Skarels struct mscp_info ki_mi; /* MSCP info (per mscpvar.h) */ 11834293Skarels struct buf ki_tab; /* controller queue */ 11934293Skarels 12034293Skarels /* stuff read and written by hardware */ 12134293Skarels struct kdbca ki_ca; /* communications area */ 12234293Skarels struct mscp ki_rsp[NRSP]; /* response packets */ 12334293Skarels struct mscp ki_cmd[NCMD]; /* command packets */ 12434293Skarels } kdbinfo[NKDB]; 12534293Skarels 12634293Skarels #define ki_ctlr ki_mi.mi_ctlr 12734293Skarels 12834293Skarels /* 12934293Skarels * Controller states 13034293Skarels */ 13134293Skarels #define ST_IDLE 0 /* uninitialised */ 13234293Skarels #define ST_STEP1 1 /* in `STEP 1' */ 13334293Skarels #define ST_STEP2 2 /* in `STEP 2' */ 13434293Skarels #define ST_STEP3 3 /* in `STEP 3' */ 13534293Skarels #define ST_SETCHAR 4 /* in `Set Controller Characteristics' */ 13634293Skarels #define ST_RUN 5 /* up and running */ 13734293Skarels 13834293Skarels /* 13934293Skarels * Flags 14034293Skarels */ 14134293Skarels #define KDB_ALIVE 0x01 /* this KDB50 exists */ 14234293Skarels #define KDB_GRIPED 0x04 /* griped about cmd ring too small */ 14334293Skarels #define KDB_INSLAVE 0x08 /* inside kdbslave() */ 14434293Skarels #define KDB_DOWAKE 0x10 /* wakeup when ctlr init done */ 14534293Skarels 14634293Skarels struct kdbstats kdbstats; /* statistics */ 14734293Skarels 14834293Skarels /* 14934293Skarels * Device to unit number and partition: 15034293Skarels */ 15134293Skarels #define UNITSHIFT 3 15234293Skarels #define UNITMASK 7 15334293Skarels #define kdbunit(dev) (minor(dev) >> UNITSHIFT) 15434293Skarels #define kdbpart(dev) (minor(dev) & UNITMASK) 15534293Skarels 15634293Skarels /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ 15734293Skarels /* THESE SHOULD BE SHARED WITH uda.c (but not yet) */ 15834293Skarels struct size { 15934293Skarels daddr_t nblocks; 16034293Skarels daddr_t blkoff; 16134293Skarels } kra81_sizes[8] = { 16234293Skarels #ifdef MARYLAND 16334293Skarels 67832, 0, /* A=cyl 0 thru 94 + 2 sectors */ 16434293Skarels 67828, 67832, /* B=cyl 95 thru 189 - 2 sectors */ 16534293Skarels -1, 0, /* C=cyl 0 thru 1247 */ 16634293Skarels -1, 135660, /* D=cyl 190 thru 1247 */ 16734293Skarels 449466, 49324, /* E xxx */ 16834293Skarels 64260, 498790, /* F xxx */ 16934293Skarels 328022, 563050, /* G xxx */ 17034293Skarels 0, 0, 17134293Skarels #else 17234293Skarels 15884, 0, /* a */ 17334293Skarels 33440, 15884, /* b */ 17434293Skarels -1, 0, /* c */ 17534293Skarels -1, 49324, /* d */ 17634293Skarels 449466, 49324, /* e */ 17734293Skarels 64260, 498790, /* f */ 17834293Skarels 328022, 563050, /* g */ 17934293Skarels 0, 0, 18034293Skarels #endif 18134293Skarels }, kra80_sizes[8] = { 18234293Skarels 15884, 0, /* A=blk 0 thru 15883 */ 18334293Skarels 33440, 15884, /* B=blk 15884 thru 49323 */ 18434293Skarels -1, 0, /* C=blk 0 thru end */ 18534293Skarels 0, 0, 18634293Skarels 0, 0, 18734293Skarels 0, 0, 18834293Skarels 82080, 49324, /* G=blk 49324 thru 131403 */ 18934293Skarels -1, 131404, /* H=blk 131404 thru end */ 19034293Skarels }, kra60_sizes[8] = { 19134293Skarels 15884, 0, /* A=blk 0 thru 15883 */ 19234293Skarels 33440, 15884, /* B=blk 15884 thru 49323 */ 19334293Skarels -1, 0, /* C=blk 0 thru end */ 19434293Skarels -1, 49324, /* D=blk 49324 thru end */ 19534293Skarels 0, 0, 19634293Skarels 0, 0, 19734293Skarels 82080, 49324, /* G=blk 49324 thru 131403 */ 19834293Skarels -1, 131404, /* H=blk 131404 thru end */ 19934293Skarels }; 20034293Skarels /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ 20134293Skarels 20234293Skarels /* 20334293Skarels * Drive type index decoding table. `ut_name' is null iff the 20434293Skarels * type is not known. 20534293Skarels */ 20634293Skarels struct kdbtypes { 20734293Skarels char *ut_name; /* drive type name */ 20834293Skarels struct size *ut_sizes; /* partition tables */ 20934293Skarels } kdbtypes[] = { 21034293Skarels NULL, NULL, 21134293Skarels "ra80", kra80_sizes, /* 1 = ra80 */ 21234293Skarels NULL, NULL, 21334293Skarels NULL, NULL, 21434293Skarels "ra60", kra60_sizes, /* 4 = ra60 */ 21534293Skarels "ra81", kra81_sizes, /* 5 = ra81 */ 21634293Skarels }; 21734293Skarels 21834293Skarels #define NTYPES 6 21934293Skarels 22034293Skarels /* 22134293Skarels * Definition of the driver for autoconf and generic MSCP code. 22234293Skarels * SOME OF THIS IS BOGUS (must fix config) 22334293Skarels */ 22434293Skarels 22534293Skarels #ifdef notdef /* not when driver is for kra disks */ 22634293Skarels /* 22734293Skarels * Some of these variables (per-drive stuff) are shared 22834293Skarels * with the UDA50 code (why not, they are the same drives). 22934293Skarels * N.B.: kdbdinfo must not be shared. 23034293Skarels */ 23134293Skarels #define kdbutab udautab /* shared */ 23234293Skarels #define kdbslavereply udaslavereply /* shared */ 23334293Skarels #endif 23434293Skarels 23534293Skarels int kdbprobe(); /* XXX */ 23634293Skarels int kdbslave(), kdbattach(); 23734293Skarels 23834293Skarels int kdbdgram(), kdbctlrdone(), kdbunconf(), kdbiodone(); 23934293Skarels int kdbonline(), kdbgotstatus(), kdbioerror(); 24034293Skarels 24134293Skarels struct uba_device *kdbdinfo[NKRA]; /* uba_device indeed! */ 24234293Skarels struct buf kdbutab[NKRA]; /* per drive transfer queue */ 24334293Skarels 24434293Skarels u_short kdbstd[] = { 0 }; /* XXX */ 24534293Skarels struct uba_driver kdbdriver = /* XXX */ 24634293Skarels { kdbprobe, kdbslave, kdbattach, 0, kdbstd, DRIVENAMES, kdbdinfo, "kdb" }; 24734293Skarels 24834293Skarels struct mscp_driver kdbmscpdriver = 24934552Skarels { MAXUNIT, NKRA, UNITSHIFT, kdbutab, (struct disklabel *)0, kdbdinfo, 25034293Skarels kdbdgram, kdbctlrdone, kdbunconf, kdbiodone, 25134293Skarels kdbonline, kdbgotstatus, NULL, kdbioerror, NULL, 25234293Skarels "kdb", DRIVENAMES }; 25334293Skarels 25434293Skarels /* 25534293Skarels * Miscellaneous private variables. 25634293Skarels */ 25734293Skarels char kdbsr_bits[] = KDBSR_BITS; 25834293Skarels 25934293Skarels struct uba_device *kdbip[NKDB][MAXUNIT]; 26034293Skarels /* inverting pointers: ctlr & unit => `Unibus' 26134293Skarels device pointer */ 26234293Skarels 26334293Skarels daddr_t ra_dsize[NKRA]; /* drive sizes, from on line end packets */ 26434293Skarels 26534293Skarels struct mscp kdbslavereply; /* get unit status response packet, set 26634293Skarels for kdbslave by kdbunconf, via kdbintr */ 26734293Skarels 26834293Skarels int kdbwstart, kdbwatch(); /* watchdog timer */ 26934293Skarels int wakeup(); 27034293Skarels 27134293Skarels /* 27234293Skarels * If kdbprobe is called, return 0 to keep Unibus code from attempting 27334293Skarels * to use this device. XXX rethink 27434293Skarels */ 27534293Skarels /* ARGSUSED */ 27634293Skarels kdbprobe(reg, ctlr) 27734293Skarels caddr_t reg; 27834293Skarels int ctlr; 27934293Skarels { 28034293Skarels 28134293Skarels return (0); 28234293Skarels } 28334293Skarels 28434293Skarels /* 28534293Skarels * Configure in a KDB50 controller. 28634293Skarels */ 28734293Skarels kdbconfig(kdbnum, va, pa, vec) 28834293Skarels int kdbnum; 28934293Skarels struct biiregs *va, *pa; 29034293Skarels int vec; 29134293Skarels { 29234293Skarels register struct kdbinfo *ki; 29334293Skarels #define mi (&ki->ki_mi) 29434293Skarels 29534293Skarels #ifdef lint 29634293Skarels extern int (*kdbint0[])(); 29734293Skarels 29834293Skarels (*kdbint0[0])(0); /* this is a config botch */ 29934293Skarels kdbintr(0); 30034293Skarels #endif 30134293Skarels 30234293Skarels /* 30334293Skarels * Set up local KDB status. 30434293Skarels */ 30534293Skarels ki = &kdbinfo[kdbnum]; 30634757Sbostic ki->ki_kdb = (struct kdb_regs *)va; 30734757Sbostic ki->ki_physkdb = (struct kdb_regs *)pa; 30834293Skarels ki->ki_vec = vec; 30934510Skarels ki->ki_map = 31034757Sbostic (struct map *)malloc((u_long)(KI_MAPSIZ * sizeof(struct map)), 31134293Skarels M_DEVBUF, M_NOWAIT); 31234757Sbostic if (ki->ki_map == NULL) { 31334757Sbostic printf("kdb%d: cannot get memory for ptes\n", kdbnum); 31434293Skarels return; 31534757Sbostic } 31634757Sbostic ki->ki_ptephys = PHYS(long, ki->ki_pte); /* kvtophys(ki->ki_pte) */ 31734293Skarels ki->ki_flags = KDB_ALIVE; 31834293Skarels 31934757Sbostic /* THE FOLLOWING IS ONLY NEEDED TO CIRCUMVENT A BUG IN rminit */ 32034757Sbostic bzero((caddr_t)ki->ki_map, KI_MAPSIZ * sizeof(struct map)); 32134757Sbostic 32234293Skarels rminit(ki->ki_map, (long)KI_PTES, (long)1, "kdb", KI_MAPSIZ); 32334293Skarels 32434293Skarels /* 32534293Skarels * Set up the generic MSCP structures. 32634293Skarels */ 32734293Skarels mi->mi_md = &kdbmscpdriver; 32834293Skarels mi->mi_ctlr = kdbnum; /* also sets ki->ki_ctlr */ 32934293Skarels mi->mi_tab = &ki->ki_tab; 33034293Skarels mi->mi_ip = kdbip[kdbnum]; 33134293Skarels mi->mi_cmd.mri_size = NCMD; 33234293Skarels mi->mi_cmd.mri_desc = ki->ki_ca.ca_cmddsc; 33334293Skarels mi->mi_cmd.mri_ring = ki->ki_cmd; 33434293Skarels mi->mi_rsp.mri_size = NRSP; 33534293Skarels mi->mi_rsp.mri_desc = ki->ki_ca.ca_rspdsc; 33634293Skarels mi->mi_rsp.mri_ring = ki->ki_rsp; 33734293Skarels mi->mi_wtab.av_forw = mi->mi_wtab.av_back = &mi->mi_wtab; 33834293Skarels #undef mi 33934293Skarels } 34034293Skarels 34134293Skarels /* 34234293Skarels * Find a slave. 34334293Skarels * Note that by the time kdbslave is called, the interrupt vector 34434293Skarels * for the KDB50 has been set up (so that kdbunconf() will be called). 34534293Skarels */ 34634293Skarels kdbslave(ui) 34734293Skarels register struct uba_device *ui; 34834293Skarels { 34934293Skarels register struct kdbinfo *ki; 35034293Skarels register struct mscp *mp; 35134293Skarels int next = 0, type, timeout, tries, i; 35234293Skarels 35334293Skarels #ifdef lint 35434293Skarels i = 0; i = i; 35534293Skarels #endif 35634293Skarels /* 35734293Skarels * Make sure the controller is fully initialised, by waiting 35834293Skarels * for it if necessary. 35934293Skarels */ 36034293Skarels ki = &kdbinfo[ui->ui_ctlr]; 36134293Skarels if (ki->ki_state == ST_RUN) 36234293Skarels goto findunit; 36334293Skarels tries = 0; 36434293Skarels again: 36534293Skarels if (kdbinit(ki)) 36634293Skarels return (0); 36734293Skarels timeout = todr() + 1000; /* 10 seconds */ 36834293Skarels while (todr() < timeout) 36934293Skarels if (ki->ki_state == ST_RUN) /* made it */ 37034293Skarels goto findunit; 37134293Skarels if (++tries < 2) 37234293Skarels goto again; 37334293Skarels printf("kdb%d: controller hung\n", ki->ki_ctlr); 37434293Skarels return (0); 37534293Skarels 37634293Skarels /* 37734293Skarels * The controller is all set; go find the unit. Grab an 37834293Skarels * MSCP packet and send out a Get Unit Status command, with 37934293Skarels * the `next unit' modifier if we are looking for a generic 38034293Skarels * unit. We set the `in slave' flag so that kdbunconf() 38134293Skarels * knows to copy the response to `kdbslavereply'. 38234293Skarels */ 38334293Skarels findunit: 38434293Skarels kdbslavereply.mscp_opcode = 0; 38534293Skarels ki->ki_flags |= KDB_INSLAVE; 38634293Skarels if ((mp = mscp_getcp(&ki->ki_mi, MSCP_DONTWAIT)) == NULL) 38734293Skarels panic("kdbslave"); /* `cannot happen' */ 38834293Skarels mp->mscp_opcode = M_OP_GETUNITST; 38934293Skarels if (ui->ui_slave == '?') { 39034293Skarels mp->mscp_unit = next; 39134293Skarels mp->mscp_modifier = M_GUM_NEXTUNIT; 39234293Skarels } else { 39334293Skarels mp->mscp_unit = ui->ui_slave; 39434293Skarels mp->mscp_modifier = 0; 39534293Skarels } 39634293Skarels *mp->mscp_addr |= MSCP_OWN | MSCP_INT; 39734293Skarels i = ki->ki_kdb->kdb_ip; /* initiate polling */ 39834293Skarels mp = &kdbslavereply; 39934293Skarels timeout = todr() + 1000; 40034293Skarels while (todr() < timeout) 40134293Skarels if (mp->mscp_opcode) 40234293Skarels goto gotit; 40334293Skarels printf("kdb%d: no response to Get Unit Status request\n", 40434293Skarels ki->ki_ctlr); 40534293Skarels ki->ki_flags &= ~KDB_INSLAVE; 40634293Skarels return (0); 40734293Skarels 40834293Skarels gotit: 40934293Skarels ki->ki_flags &= ~KDB_INSLAVE; 41034293Skarels 41134293Skarels /* 41234293Skarels * Got a slave response. If the unit is there, use it. 41334293Skarels */ 41434293Skarels switch (mp->mscp_status & M_ST_MASK) { 41534293Skarels 41634293Skarels case M_ST_SUCCESS: /* worked */ 41734293Skarels case M_ST_AVAILABLE: /* found another drive */ 41834293Skarels break; /* use it */ 41934293Skarels 42034293Skarels case M_ST_OFFLINE: 42134293Skarels /* 42234293Skarels * Figure out why it is off line. It may be because 42334293Skarels * it is nonexistent, or because it is spun down, or 42434293Skarels * for some other reason. 42534293Skarels */ 42634293Skarels switch (mp->mscp_status & ~M_ST_MASK) { 42734293Skarels 42834293Skarels case M_OFFLINE_UNKNOWN: 42934293Skarels /* 43034293Skarels * No such drive, and there are none with 43134293Skarels * higher unit numbers either, if we are 43234293Skarels * using M_GUM_NEXTUNIT. 43334293Skarels */ 43434293Skarels return (0); 43534293Skarels 43634293Skarels case M_OFFLINE_UNMOUNTED: 43734293Skarels /* 43834293Skarels * The drive is not spun up. Use it anyway. 43934293Skarels * 44034293Skarels * N.B.: this seems to be a common occurrance 44134293Skarels * after a power failure. The first attempt 44234293Skarels * to bring it on line seems to spin it up 44334293Skarels * (and thus takes several minutes). Perhaps 44434293Skarels * we should note here that the on-line may 44534293Skarels * take longer than usual. 44634293Skarels */ 44734293Skarels break; 44834293Skarels 44934293Skarels default: 45034293Skarels /* 45134293Skarels * In service, or something else equally unusable. 45234293Skarels */ 45334757Sbostic printf("kdb%d: unit %d off line:", ki->ki_ctlr, 45434293Skarels mp->mscp_unit); 45534293Skarels mscp_printevent(mp); 45634293Skarels goto try_another; 45734293Skarels } 45834293Skarels break; 45934293Skarels 46034293Skarels default: 46134757Sbostic printf("kdb%d: unable to get unit status:", ki->ki_ctlr); 46234293Skarels mscp_printevent(mp); 46334293Skarels return (0); 46434293Skarels } 46534293Skarels 46634293Skarels /* 46734293Skarels * Does this ever happen? What (if anything) does it mean? 46834293Skarels */ 46934293Skarels if (mp->mscp_unit < next) { 47034293Skarels printf("kdb%d: unit %d, next %d\n", 47134293Skarels ki->ki_ctlr, mp->mscp_unit, next); 47234293Skarels return (0); 47334293Skarels } 47434293Skarels 47534293Skarels if (mp->mscp_unit >= MAXUNIT) { 47634293Skarels printf("kdb%d: cannot handle unit number %d (max is %d)\n", 47734293Skarels ki->ki_ctlr, mp->mscp_unit, MAXUNIT - 1); 47834293Skarels return (0); 47934293Skarels } 48034293Skarels 48134293Skarels /* 48234293Skarels * See if we already handle this drive. 48334293Skarels * (Only likely if ui->ui_slave=='?'.) 48434293Skarels */ 48534293Skarels if (kdbip[ki->ki_ctlr][mp->mscp_unit] != NULL) 48634293Skarels goto try_another; 48734293Skarels 48834293Skarels /* 48934293Skarels * Make sure we know about this kind of drive. 49034293Skarels * Others say we should treat unknowns as RA81s; I am 49134293Skarels * not sure this is safe. 49234293Skarels */ 49334293Skarels type = mp->mscp_guse.guse_drivetype; 49434293Skarels if (type >= NTYPES || kdbtypes[type].ut_name == 0) { 49534293Skarels register long id = mp->mscp_guse.guse_mediaid; 49634293Skarels 49734293Skarels printf("kdb%d: unit %d: media ID `", ki->ki_ctlr, 49834293Skarels mp->mscp_unit); 49934293Skarels printf("%c%c %c%c%c%d", 50034293Skarels MSCP_MID_CHAR(4, id), MSCP_MID_CHAR(3, id), 50134293Skarels MSCP_MID_CHAR(2, id), MSCP_MID_CHAR(1, id), 50234293Skarels MSCP_MID_CHAR(0, id), MSCP_MID_NUM(id)); 50334293Skarels printf("' is of unknown type %d; ignored\n", type); 50434293Skarels try_another: 50534293Skarels if (ui->ui_slave != '?') 50634293Skarels return (0); 50734293Skarels next = mp->mscp_unit + 1; 50834293Skarels goto findunit; 50934293Skarels } 51034293Skarels 51134293Skarels /* 51234293Skarels * Voila! 51334293Skarels */ 51434293Skarels ui->ui_type = type; 51534293Skarels ui->ui_flags = 0; /* not on line, nor anything else */ 51634293Skarels ui->ui_slave = mp->mscp_unit; 51734293Skarels return (1); 51834293Skarels } 51934293Skarels 52034293Skarels /* 52134293Skarels * Attach a found slave. Make sure the watchdog timer is running. 522*38171Smckusick * If this disk is being profiled, fill in the `wpms' value (used by 52334293Skarels * what?). Set up the inverting pointer, and attempt to bring the 52434293Skarels * drive on line. 52534293Skarels */ 52634293Skarels kdbattach(ui) 52734293Skarels register struct uba_device *ui; 52834293Skarels { 52934293Skarels 53034293Skarels if (kdbwstart == 0) { 53134757Sbostic timeout(kdbwatch, (caddr_t)0, hz); 53234293Skarels kdbwstart++; 53334293Skarels } 53434293Skarels if (ui->ui_dk >= 0) 535*38171Smckusick dk_wpms[ui->ui_dk] = (60 * 31 * 256); /* approx */ 53634293Skarels kdbip[ui->ui_ctlr][ui->ui_slave] = ui; 53734293Skarels (void) kdb_bringonline(ui, 1); 53834293Skarels /* should we get its status too? */ 53934293Skarels } 54034293Skarels 54134293Skarels /* 54234293Skarels * Initialise a KDB50. Return true iff something goes wrong. 54334293Skarels */ 54434293Skarels kdbinit(ki) 54534293Skarels register struct kdbinfo *ki; 54634293Skarels { 54734293Skarels register struct kdb_regs *ka = ki->ki_kdb; 54834293Skarels int timo; 54934293Skarels 55034293Skarels /* 55134293Skarels * While we are thinking about it, reset the next command 55234293Skarels * and response indicies. 55334293Skarels */ 55434293Skarels ki->ki_mi.mi_cmd.mri_next = 0; 55534293Skarels ki->ki_mi.mi_rsp.mri_next = 0; 55634293Skarels 55734293Skarels /* 55834293Skarels * Start up the hardware initialisation sequence. 55934293Skarels */ 56034293Skarels #define STEP0MASK (KDB_ERR | KDB_STEP4 | KDB_STEP3 | KDB_STEP2 | KDB_STEP1) 56134293Skarels 56234293Skarels ki->ki_state = ST_IDLE; /* in case init fails */ 56334293Skarels 56434293Skarels bi_reset(&ka->kdb_bi); /* reset bi node (but not the BI itself) */ 56534293Skarels 56634293Skarels timo = todr() + 1000; 56734293Skarels while ((ka->kdb_sa & STEP0MASK) == 0) { 56834293Skarels if (todr() > timo) { 56934293Skarels printf("kdb%d: timeout during init\n", ki->ki_ctlr); 57034293Skarels return (-1); 57134293Skarels } 57234293Skarels } 57334293Skarels if ((ka->kdb_sa & STEP0MASK) != KDB_STEP1) { 57434293Skarels printf("kdb%d: init failed, sa=%b\n", ki->ki_ctlr, 57534293Skarels ka->kdb_sa, kdbsr_bits); 57634293Skarels return (-1); 57734293Skarels } 57834293Skarels 57934293Skarels /* 58034293Skarels * Success! Record new state, and start step 1 initialisation. 58134293Skarels * The rest is done in the interrupt handler. 58234293Skarels */ 58334293Skarels ki->ki_state = ST_STEP1; 58434293Skarels ka->kdb_bi.bi_intrdes = 1 << mastercpu; 58534293Skarels #ifdef unneeded /* is it? */ 58634293Skarels ka->kdb_bi.bi_csr = (ka->kdb_bi.bi_csr&~BICSR_ARB_MASK)|BICSR_ARB_???; 58734293Skarels #endif 58834293Skarels ka->kdb_bi.bi_bcicsr |= BCI_STOPEN | BCI_IDENTEN | BCI_UINTEN | 58934293Skarels BCI_INTEN; 59034293Skarels 59134293Skarels /* I THINK THIS IS WRONG */ 59234293Skarels /* Mach uses 0x601d0, which includes IPL16, but 1d0 is IPL17, nexzvec...? */ 59334293Skarels ka->kdb_bi.bi_eintrcsr = BIEIC_IPL15 | ki->ki_vec; /* ??? */ 59434293Skarels /* END I THINK WRONG */ 59534293Skarels 59634293Skarels ka->kdb_bi.bi_uintrcsr = ki->ki_vec; 59734293Skarels ka->kdb_sw = KDB_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) | KDB_IE | 59834293Skarels (ki->ki_vec >> 2); 59934293Skarels return (0); 60034293Skarels } 60134293Skarels 60234293Skarels /* 60334293Skarels * Open a drive. 60434293Skarels */ 60534293Skarels /*ARGSUSED*/ 60634293Skarels kdbopen(dev, flag) 60734293Skarels dev_t dev; 60834293Skarels int flag; 60934293Skarels { 61034293Skarels register int unit; 61134293Skarels register struct uba_device *ui; 61234293Skarels register struct kdbinfo *ki; 61334293Skarels int s; 61434293Skarels 61534293Skarels /* 61634293Skarels * Make sure this is a reasonable open request. 61734293Skarels */ 61834293Skarels unit = kdbunit(dev); 61934293Skarels if (unit >= NKRA || (ui = kdbdinfo[unit]) == 0 || ui->ui_alive == 0) 62034293Skarels return (ENXIO); 62134293Skarels 62234293Skarels /* 62334293Skarels * Make sure the controller is running, by (re)initialising it if 62434293Skarels * necessary. 62534293Skarels */ 62634293Skarels ki = &kdbinfo[ui->ui_ctlr]; 62734293Skarels s = spl5(); 62834293Skarels if (ki->ki_state != ST_RUN) { 62934293Skarels if (ki->ki_state == ST_IDLE && kdbinit(ki)) { 63034293Skarels splx(s); 63134293Skarels return (EIO); 63234293Skarels } 63334293Skarels /* 63434293Skarels * In case it does not come up, make sure we will be 63534293Skarels * restarted in 10 seconds. This corresponds to the 63634293Skarels * 10 second timeouts in kdbprobe() and kdbslave(). 63734293Skarels */ 63834293Skarels ki->ki_flags |= KDB_DOWAKE; 63934757Sbostic timeout(wakeup, (caddr_t)&ki->ki_flags, 10 * hz); 64034757Sbostic sleep((caddr_t)&ki->ki_flags, PRIBIO); 64134293Skarels if (ki->ki_state != ST_RUN) { 64234293Skarels splx(s); 64334293Skarels printf("kdb%d: controller hung\n", ui->ui_ctlr); 64434293Skarels return (EIO); 64534293Skarels } 64634757Sbostic untimeout(wakeup, (caddr_t)&ki->ki_flags); 64734293Skarels } 64834293Skarels if ((ui->ui_flags & UNIT_ONLINE) == 0) { 64934293Skarels /* 65034293Skarels * Bring the drive on line so we can find out how 65134293Skarels * big it is. If it is not spun up, it will not 65234293Skarels * come on line; this cannot really be considered 65334293Skarels * an `error condition'. 65434293Skarels */ 65534293Skarels if (kdb_bringonline(ui, 0)) { 65634293Skarels splx(s); 65734293Skarels printf("%s%d: drive will not come on line\n", 65834293Skarels kdbdriver.ud_dname, unit); 65934293Skarels return (EIO); 66034293Skarels } 66134293Skarels } 66234293Skarels splx(s); 66334293Skarels return (0); 66434293Skarels } 66534293Skarels 66634293Skarels /* 66734293Skarels * Bring a drive on line. In case it fails to respond, we set 66834293Skarels * a timeout on it. The `nosleep' parameter should be set if 66934293Skarels * we are to spin-wait; otherwise this must be called at spl5(). 67034293Skarels */ 67134293Skarels kdb_bringonline(ui, nosleep) 67234293Skarels register struct uba_device *ui; 67334293Skarels int nosleep; 67434293Skarels { 67534293Skarels register struct kdbinfo *ki = &kdbinfo[ui->ui_ctlr]; 67634293Skarels register struct mscp *mp; 67734293Skarels int i; 67834293Skarels 67934293Skarels if (nosleep) { 68034293Skarels mp = mscp_getcp(&ki->ki_mi, MSCP_DONTWAIT); 68134293Skarels if (mp == NULL) 68234293Skarels return (-1); 68334293Skarels } else 68434293Skarels mp = mscp_getcp(&ki->ki_mi, MSCP_WAIT); 68534293Skarels mp->mscp_opcode = M_OP_ONLINE; 68634293Skarels mp->mscp_unit = ui->ui_slave; 68734757Sbostic mp->mscp_cmdref = (long)&ui->ui_flags; 68834293Skarels *mp->mscp_addr |= MSCP_OWN | MSCP_INT; 68934293Skarels i = ki->ki_kdb->kdb_ip; 69034293Skarels 69134293Skarels if (nosleep) { 69234293Skarels i = todr() + 1000; 69334293Skarels while ((ui->ui_flags & UNIT_ONLINE) == 0) 69434293Skarels if (todr() > i) 69534293Skarels return (-1); 69634293Skarels } else { 69734757Sbostic timeout(wakeup, (caddr_t)&ui->ui_flags, 10 * hz); 69834757Sbostic sleep((caddr_t)&ui->ui_flags, PRIBIO); 69934293Skarels if ((ui->ui_flags & UNIT_ONLINE) == 0) 70034293Skarels return (-1); 70134757Sbostic untimeout(wakeup, (caddr_t)&ui->ui_flags); 70234293Skarels } 70334293Skarels return (0); /* made it */ 70434293Skarels } 70534293Skarels 70634293Skarels /* 70734293Skarels * Queue a transfer request, and if possible, hand it to the controller. 70834293Skarels * 70934293Skarels * This routine is broken into two so that the internal version 71034293Skarels * kdbstrat1() can be called by the (nonexistent, as yet) bad block 71134293Skarels * revectoring routine. 71234293Skarels */ 71334293Skarels kdbstrategy(bp) 71434293Skarels register struct buf *bp; 71534293Skarels { 71634293Skarels register int unit; 71734293Skarels register struct uba_device *ui; 71834293Skarels register struct size *st; 71934293Skarels daddr_t sz, maxsz; 72034293Skarels 72134293Skarels /* 72234293Skarels * Make sure this is a reasonable drive to use. 72334293Skarels */ 72434293Skarels if ((unit = kdbunit(bp->b_dev)) >= NKRA || 72534293Skarels (ui = kdbdinfo[unit]) == NULL || ui->ui_alive == 0) { 72634293Skarels bp->b_error = ENXIO; 72734293Skarels bp->b_flags |= B_ERROR; 72834293Skarels biodone(bp); 72934293Skarels return; 73034293Skarels } 73134293Skarels 73234293Skarels /* 73334293Skarels * Determine the size of the transfer, and make sure it is 73434293Skarels * within the boundaries of the drive. 73534293Skarels */ 73634293Skarels sz = (bp->b_bcount + 511) >> 9; 73734293Skarels st = &kdbtypes[ui->ui_type].ut_sizes[kdbpart(bp->b_dev)]; 73834293Skarels if ((maxsz = st->nblocks) < 0) 73934293Skarels maxsz = ra_dsize[unit] - st->blkoff; 74034293Skarels if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz || 74134293Skarels st->blkoff >= ra_dsize[unit]) { 74234293Skarels /* if exactly at end of disk, return an EOF */ 74334293Skarels if (bp->b_blkno == maxsz) 74434293Skarels bp->b_resid = bp->b_bcount; 74534293Skarels else { 74634293Skarels bp->b_error = EINVAL; 74734293Skarels bp->b_flags |= B_ERROR; 74834293Skarels } 74934293Skarels biodone(bp); 75034293Skarels return; 75134293Skarels } 75234293Skarels kdbstrat1(bp); 75334293Skarels } 75434293Skarels 75534293Skarels /* 75634293Skarels * Work routine for kdbstrategy. 75734293Skarels */ 75834293Skarels kdbstrat1(bp) 75934293Skarels register struct buf *bp; 76034293Skarels { 76134293Skarels register int unit = kdbunit(bp->b_dev); 76234293Skarels register struct buf *dp; 76334293Skarels register struct kdbinfo *ki; 76434293Skarels struct uba_device *ui; 76534293Skarels int s; 76634293Skarels 76734293Skarels /* 76834293Skarels * Append the buffer to the drive queue, and if it is not 76934293Skarels * already there, the drive to the controller queue. (However, 77034293Skarels * if the drive queue is marked to be requeued, we must be 77134293Skarels * awaiting an on line or get unit status command; in this 77234293Skarels * case, leave it off the controller queue.) 77334293Skarels */ 77434293Skarels ui = kdbdinfo[unit]; 77534293Skarels ki = &kdbinfo[ui->ui_ctlr]; 77634293Skarels dp = &kdbutab[unit]; 77734293Skarels s = spl5(); 77834293Skarels APPEND(bp, dp, av_forw); 77934293Skarels if (dp->b_active == 0 && (ui->ui_flags & UNIT_REQUEUE) == 0) { 78034293Skarels APPEND(dp, &ki->ki_tab, b_forw); 78134293Skarels dp->b_active++; 78234293Skarels } 78334293Skarels 78434293Skarels /* 78534293Skarels * Start activity on the controller. 78634293Skarels */ 78734293Skarels kdbstart(ki); 78834293Skarels splx(s); 78934293Skarels } 79034293Skarels 79134293Skarels /* 79234293Skarels * Find the physical address of some contiguous PTEs that map the 79334293Skarels * transfer described in `bp', creating them (by copying) if 79434293Skarels * necessary. Store the physical base address of the map through 79534293Skarels * mapbase, and the page offset through offset, and any resource 79634293Skarels * information in *info (or 0 if none). 79734293Skarels * 79834293Skarels * If we cannot allocate space, return a nonzero status. 79934293Skarels */ 80034293Skarels int 80134293Skarels kdbmap(ki, bp, mapbase, offset, info) 80234293Skarels struct kdbinfo *ki; 80334293Skarels register struct buf *bp; 80434293Skarels long *mapbase, *offset; 80534293Skarels int *info; 80634293Skarels { 80734293Skarels register struct pte *spte, *dpte; 80834293Skarels register struct proc *rp; 80934293Skarels register int i, a, o; 81034293Skarels u_int v; 81134293Skarels int npf; 81234293Skarels 81334293Skarels o = (int)bp->b_un.b_addr & PGOFSET; 81434293Skarels 81534293Skarels /* handle contiguous cases */ 81634293Skarels if ((bp->b_flags & B_PHYS) == 0) { 81734293Skarels spte = kvtopte(bp->b_un.b_addr); 81834293Skarels kdbstats.ks_sys++; 81934293Skarels *mapbase = PHYS(long, spte); 82034293Skarels *offset = o; 82134293Skarels *info = 0; 82234293Skarels return (0); 82334293Skarels } 82434293Skarels if (bp->b_flags & B_PAGET) { 82534293Skarels spte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)]; 82634293Skarels if (spte->pg_v == 0) panic("kdbmap"); 82734293Skarels kdbstats.ks_paget++; 82834293Skarels *mapbase = PHYS(long, spte); 82934293Skarels *offset = o; 83034293Skarels *info = 0; 83134293Skarels return (0); 83234293Skarels } 83334293Skarels 83434293Skarels /* potentially discontiguous or invalid ptes */ 83534293Skarels v = btop(bp->b_un.b_addr); 83634293Skarels rp = bp->b_flags & B_DIRTY ? &proc[2] : bp->b_proc; 83734293Skarels if (bp->b_flags & B_UAREA) 83834293Skarels spte = &rp->p_addr[v]; 83934293Skarels else 84034293Skarels spte = vtopte(rp, v); 84134293Skarels npf = btoc(bp->b_bcount + o); 84234293Skarels 84334293Skarels #ifdef notdef 84434293Skarels /* 84534293Skarels * The current implementation of the VM system requires 84634293Skarels * that all of these be done with a copy. Even if the 84734293Skarels * PTEs could be used now, they may be snatched out from 84834293Skarels * under us later. It would be nice if we could stop that.... 84934293Skarels */ 85034293Skarels 85134293Skarels /* check for invalid */ 85234293Skarels /* CONSIDER CHANGING VM TO VALIDATE PAGES EARLIER */ 85334293Skarels for (dpte = spte, i = npf; --i >= 0; dpte++) 85434293Skarels if (dpte->pg_v == 0) 85534293Skarels goto copy1; 85634293Skarels /* 85734293Skarels * Check for discontiguous physical pte addresses. It is 85834293Skarels * not necessary to check each pte, since they come in clumps 85934293Skarels * of pages. 86034293Skarels */ 86134293Skarels i = howmany(npf + (((int)spte & PGOFSET) / sizeof (*spte)), NPTEPG); 86234293Skarels /* often i==1, and we can avoid work */ 86334293Skarels if (--i > 0) { 86434293Skarels dpte = kvtopte(spte); 86534293Skarels a = dpte->pg_pfnum; 86634293Skarels while (--i >= 0) 86734293Skarels if ((++dpte)->pg_pfnum != ++a) 86834293Skarels goto copy2; 86934293Skarels } 87034293Skarels 87134293Skarels /* made it */ 87234293Skarels kdbstats.ks_contig++; 87334293Skarels *mapbase = kvtophys(spte); 87434293Skarels *offset = o; 87534293Skarels *info = 0; 87634293Skarels return (0); 87734293Skarels 87834293Skarels copy1: 87934293Skarels kdbstats.ks_inval++; /* temp */ 88034293Skarels copy2: 88134293Skarels #endif /* notdef */ 88234293Skarels kdbstats.ks_copies++; 88334293Skarels i = npf + 1; 88434757Sbostic if ((a = rmalloc(ki->ki_map, (long)i)) == 0) { 88534293Skarels kdbstats.ks_mapwait++; 88634293Skarels return (-1); 88734293Skarels } 88834293Skarels *info = (i << 16) | a; 88934293Skarels a--; 89034293Skarels /* if offset > PGOFSET, btop(offset) indexes mapbase */ 89134293Skarels *mapbase = ki->ki_ptephys; 89234293Skarels *offset = (a << PGSHIFT) | o; 89334293Skarels dpte = &ki->ki_pte[a]; 89434293Skarels while (--i > 0) 89534293Skarels *(int *)dpte++ = PG_V | *(int *)spte++; 89634293Skarels *(int *)dpte = 0; 89734293Skarels return (0); 89834293Skarels } 89934293Skarels 90034293Skarels #define KDBFREE(ki, info) if (info) \ 90134293Skarels rmfree((ki)->ki_map, (long)((info) >> 16), (long)((info) & 0xffff)) 90234293Skarels 90334293Skarels /* 90434293Skarels * Start up whatever transfers we can find. 90534293Skarels * Note that kdbstart() must be called at spl5(). 90634293Skarels */ 90734293Skarels kdbstart(ki) 90834293Skarels register struct kdbinfo *ki; 90934293Skarels { 91034293Skarels register struct buf *bp, *dp; 91134293Skarels register struct mscp *mp; 91234293Skarels register struct uba_device *ui; 91334293Skarels long mapbase, offset; 91434293Skarels int info, ncmd = 0; 91534293Skarels 91634293Skarels /* 91734293Skarels * If it is not running, try (again and again...) to initialise 91834293Skarels * it. If it is currently initialising just ignore it for now. 91934293Skarels */ 92034293Skarels if (ki->ki_state != ST_RUN) { 92134293Skarels if (ki->ki_state == ST_IDLE && kdbinit(ki)) 92234293Skarels printf("kdb%d: still hung\n", ki->ki_ctlr); 92334293Skarels return; 92434293Skarels } 92534293Skarels 92634293Skarels loop: 92734293Skarels /* if insufficient credit, avoid overhead */ 92834293Skarels if (ki->ki_mi.mi_credits <= MSCP_MINCREDITS) 92934293Skarels goto out; 93034293Skarels 93134293Skarels /* 93234757Sbostic * Service the drive at the head of the queue. It may not 93334757Sbostic * need anything; eventually this will finish up the close 93434757Sbostic * protocol, but that is yet to be implemented here. 93534293Skarels */ 93634293Skarels if ((dp = ki->ki_tab.b_actf) == NULL) 93734293Skarels goto out; 93834757Sbostic if ((bp = dp->b_actf) == NULL) { 93934757Sbostic dp->b_active = 0; 94034757Sbostic ki->ki_tab.b_actf = dp->b_forw; 94134757Sbostic goto loop; 94234757Sbostic } 94334293Skarels 94434293Skarels if (ki->ki_kdb->kdb_sa & KDB_ERR) { /* ctlr fatal error */ 94534293Skarels kdbsaerror(ki); 94634293Skarels goto out; 94734293Skarels } 94834293Skarels 94934293Skarels /* find or create maps for this transfer */ 95034293Skarels if (kdbmap(ki, bp, &mapbase, &offset, &info)) 95134293Skarels goto out; /* effectively, resource wait */ 95234293Skarels 95334293Skarels /* 95434293Skarels * Get an MSCP packet, then figure out what to do. If 95534293Skarels * we cannot get a command packet, the command ring may 95634293Skarels * be too small: We should have at least as many command 95734293Skarels * packets as credits, for best performance. 95834293Skarels */ 95934293Skarels if ((mp = mscp_getcp(&ki->ki_mi, MSCP_DONTWAIT)) == NULL) { 96034293Skarels if (ki->ki_mi.mi_credits > MSCP_MINCREDITS && 96134293Skarels (ki->ki_flags & KDB_GRIPED) == 0) { 96234293Skarels log(LOG_NOTICE, "kdb%d: command ring too small\n", 96334293Skarels ki->ki_ctlr); 96434293Skarels ki->ki_flags |= KDB_GRIPED;/* complain only once */ 96534293Skarels } 96634293Skarels KDBFREE(ki, info); 96734293Skarels goto out; 96834293Skarels } 96934293Skarels 97034293Skarels /* 97134293Skarels * Bring the drive on line if it is not already. Get its status 97234293Skarels * if we do not already have it. Otherwise just start the transfer. 97334293Skarels */ 97434293Skarels ui = kdbdinfo[kdbunit(bp->b_dev)]; 97534293Skarels if ((ui->ui_flags & UNIT_ONLINE) == 0) { 97634293Skarels mp->mscp_opcode = M_OP_ONLINE; 97734293Skarels goto common; 97834293Skarels } 97934293Skarels if ((ui->ui_flags & UNIT_HAVESTATUS) == 0) { 98034293Skarels mp->mscp_opcode = M_OP_GETUNITST; 98134293Skarels common: 98234293Skarels if (ui->ui_flags & UNIT_REQUEUE) panic("kdbstart"); 98334293Skarels /* 98434293Skarels * Take the drive off the controller queue. When the 98534293Skarels * command finishes, make sure the drive is requeued. 98634293Skarels * Give up any mapping (not needed now). This last is 98734293Skarels * not efficient, but is rare. 98834293Skarels */ 98934293Skarels KDBFREE(ki, info); 99034293Skarels ki->ki_tab.b_actf = dp->b_forw; 99134293Skarels dp->b_active = 0; 99234293Skarels ui->ui_flags |= UNIT_REQUEUE; 99334293Skarels mp->mscp_unit = ui->ui_slave; 99434293Skarels *mp->mscp_addr |= MSCP_OWN | MSCP_INT; 99534293Skarels ncmd++; 99634293Skarels goto loop; 99734293Skarels } 99834293Skarels 99934293Skarels mp->mscp_opcode = (bp->b_flags & B_READ) ? M_OP_READ : M_OP_WRITE; 100034293Skarels mp->mscp_unit = ui->ui_slave; 100134293Skarels mp->mscp_seq.seq_lbn = bp->b_blkno + 100234293Skarels kdbtypes[ui->ui_type].ut_sizes[kdbpart(bp->b_dev)].blkoff; 100334293Skarels mp->mscp_seq.seq_bytecount = bp->b_bcount; 100434293Skarels 100534293Skarels mp->mscp_seq.seq_buffer = offset | KDB_MAP; 100634293Skarels mp->mscp_seq.seq_mapbase = mapbase; 100734293Skarels 100834293Skarels /* profile the drive */ 100934293Skarels if (ui->ui_dk >= 0) { 101034293Skarels dk_busy |= 1 << ui->ui_dk; 101134293Skarels dk_xfer[ui->ui_dk]++; 101234293Skarels dk_wds[ui->ui_dk] += bp->b_bcount >> 6; 101334293Skarels } 101434293Skarels 101534293Skarels /* 101634293Skarels * Fill in the rest of the MSCP packet and move the buffer to the 101734293Skarels * I/O wait queue. 101834293Skarels */ 101934293Skarels mscp_go(&ki->ki_mi, mp, info); 102034293Skarels ncmd++; /* note the transfer */ 102134293Skarels ki->ki_tab.b_active++; /* another one going */ 102234293Skarels goto loop; 102334293Skarels 102434293Skarels out: 102534293Skarels if (ncmd >= KS_MAXC) 102634293Skarels ncmd = KS_MAXC - 1; 102734293Skarels kdbstats.ks_cmd[ncmd]++; 102834293Skarels if (ncmd) /* start some transfers */ 102934293Skarels ncmd = ki->ki_kdb->kdb_ip; 103034293Skarels } 103134293Skarels 103234293Skarels /* ARGSUSED */ 103334293Skarels kdbiodone(mi, bp, info) 103434293Skarels struct mscp_info *mi; 103534293Skarels struct buf *bp; 103634293Skarels int info; 103734293Skarels { 103834293Skarels register struct kdbinfo *ki = &kdbinfo[mi->mi_ctlr]; 103934293Skarels 104034293Skarels KDBFREE(ki, info); 104134293Skarels biodone(bp); 104234293Skarels ki->ki_tab.b_active--; /* another one done */ 104334293Skarels } 104434293Skarels 104534293Skarels /* 104634293Skarels * The error bit was set in the controller status register. Gripe, 104734293Skarels * reset the controller, requeue pending transfers. 104834293Skarels */ 104934293Skarels kdbsaerror(ki) 105034293Skarels register struct kdbinfo *ki; 105134293Skarels { 105234293Skarels 105334293Skarels printf("kdb%d: controller error, sa=%b\n", ki->ki_ctlr, 105434293Skarels ki->ki_kdb->kdb_sa, kdbsr_bits); 105534293Skarels mscp_requeue(&ki->ki_mi); 105634293Skarels (void) kdbinit(ki); 105734293Skarels } 105834293Skarels 105934293Skarels /* 106034293Skarels * Interrupt routine. Depending on the state of the controller, 106134293Skarels * continue initialisation, or acknowledge command and response 106234293Skarels * interrupts, and process responses. 106334293Skarels */ 106434293Skarels kdbintr(ctlr) 106534293Skarels int ctlr; 106634293Skarels { 106734293Skarels register struct kdbinfo *ki = &kdbinfo[ctlr]; 106834293Skarels register struct kdb_regs *kdbaddr = ki->ki_kdb; 106934293Skarels register struct mscp *mp; 107034293Skarels register int i; 107134293Skarels 107234293Skarels ki->ki_wticks = 0; /* reset interrupt watchdog */ 107334293Skarels 107434293Skarels /* 107534293Skarels * Combinations during steps 1, 2, and 3: STEPnMASK 107634293Skarels * corresponds to which bits should be tested; 107734293Skarels * STEPnGOOD corresponds to the pattern that should 107834293Skarels * appear after the interrupt from STEPn initialisation. 107934293Skarels * All steps test the bits in ALLSTEPS. 108034293Skarels */ 108134293Skarels #define ALLSTEPS (KDB_ERR|KDB_STEP4|KDB_STEP3|KDB_STEP2|KDB_STEP1) 108234293Skarels 108334293Skarels #define STEP1MASK (ALLSTEPS | KDB_IE | KDB_NCNRMASK) 108434293Skarels #define STEP1GOOD (KDB_STEP2 | KDB_IE | (NCMDL2 << 3) | NRSPL2) 108534293Skarels 108634293Skarels #define STEP2MASK (ALLSTEPS | KDB_IE | KDB_IVECMASK) 108734293Skarels #define STEP2GOOD (KDB_STEP3 | KDB_IE | (ki->ki_vec >> 2)) 108834293Skarels 108934293Skarels #define STEP3MASK ALLSTEPS 109034293Skarels #define STEP3GOOD KDB_STEP4 109134293Skarels 109234293Skarels switch (ki->ki_state) { 109334293Skarels 109434293Skarels case ST_IDLE: 109534293Skarels /* 109634293Skarels * Ignore unsolicited interrupts. 109734293Skarels */ 109834293Skarels log(LOG_WARNING, "kdb%d: stray intr\n", ctlr); 109934293Skarels return; 110034293Skarels 110134293Skarels case ST_STEP1: 110234293Skarels /* 110334293Skarels * Begin step two initialisation. 110434293Skarels */ 110534293Skarels if ((kdbaddr->kdb_sa & STEP1MASK) != STEP1GOOD) { 110634293Skarels i = 1; 110734293Skarels initfailed: 110834293Skarels printf("kdb%d: init step %d failed, sa=%b\n", 110934293Skarels ctlr, i, kdbaddr->kdb_sa, kdbsr_bits); 111034293Skarels ki->ki_state = ST_IDLE; 111134293Skarels if (ki->ki_flags & KDB_DOWAKE) { 111234293Skarels ki->ki_flags &= ~KDB_DOWAKE; 111334757Sbostic wakeup((caddr_t)&ki->ki_flags); 111434293Skarels } 111534293Skarels return; 111634293Skarels } 111734293Skarels kdbaddr->kdb_sw = PHYS(int, &ki->ki_ca.ca_rspdsc[0]); 111834293Skarels ki->ki_state = ST_STEP2; 111934293Skarels return; 112034293Skarels 112134293Skarels case ST_STEP2: 112234293Skarels /* 112334293Skarels * Begin step 3 initialisation. 112434293Skarels */ 112534293Skarels if ((kdbaddr->kdb_sa & STEP2MASK) != STEP2GOOD) { 112634293Skarels i = 2; 112734293Skarels goto initfailed; 112834293Skarels } 112934293Skarels kdbaddr->kdb_sw = PHYS(int, &ki->ki_ca.ca_rspdsc[0]) >> 16; 113034293Skarels ki->ki_state = ST_STEP3; 113134293Skarels return; 113234293Skarels 113334293Skarels case ST_STEP3: 113434293Skarels /* 113534293Skarels * Set controller characteristics (finish initialisation). 113634293Skarels */ 113734293Skarels if ((kdbaddr->kdb_sa & STEP3MASK) != STEP3GOOD) { 113834293Skarels i = 3; 113934293Skarels goto initfailed; 114034293Skarels } 114134293Skarels i = kdbaddr->kdb_sa & 0xff; 114234293Skarels if (i != ki->ki_micro) { 114334293Skarels ki->ki_micro = i; 114434293Skarels printf("kdb%d: version %d model %d\n", 114534293Skarels ctlr, i & 0xf, i >> 4); 114634293Skarels } 114734293Skarels 114834293Skarels kdbaddr->kdb_sw = KDB_GO; 114934293Skarels 115034293Skarels /* initialise hardware data structures */ 115134293Skarels for (i = 0, mp = ki->ki_rsp; i < NRSP; i++, mp++) { 115234293Skarels ki->ki_ca.ca_rspdsc[i] = MSCP_OWN | MSCP_INT | 115334293Skarels PHYS(long, &ki->ki_rsp[i].mscp_cmdref); 115434293Skarels mp->mscp_addr = &ki->ki_ca.ca_rspdsc[i]; 115534293Skarels mp->mscp_msglen = MSCP_MSGLEN; 115634293Skarels } 115734293Skarels for (i = 0, mp = ki->ki_cmd; i < NCMD; i++, mp++) { 115834293Skarels ki->ki_ca.ca_cmddsc[i] = MSCP_INT | 115934293Skarels PHYS(long, &ki->ki_cmd[i].mscp_cmdref); 116034293Skarels mp->mscp_addr = &ki->ki_ca.ca_cmddsc[i]; 116134293Skarels mp->mscp_msglen = MSCP_MSGLEN; 116234293Skarels } 116334293Skarels 116434293Skarels /* 116534293Skarels * Before we can get a command packet, we need some 116634293Skarels * credits. Fake some up to keep mscp_getcp() happy, 116734293Skarels * get a packet, and cancel all credits (the right 116834293Skarels * number should come back in the response to the 116934293Skarels * SCC packet). 117034293Skarels */ 117134293Skarels ki->ki_mi.mi_credits = MSCP_MINCREDITS + 1; 117234293Skarels mp = mscp_getcp(&ki->ki_mi, MSCP_DONTWAIT); 117334293Skarels if (mp == NULL) /* `cannot happen' */ 117434293Skarels panic("kdbintr"); 117534293Skarels ki->ki_mi.mi_credits = 0; 117634293Skarels mp->mscp_opcode = M_OP_SETCTLRC; 117734293Skarels mp->mscp_unit = 0; 117834293Skarels mp->mscp_sccc.sccc_ctlrflags = M_CF_ATTN | M_CF_MISC | 117934293Skarels M_CF_THIS; 118034293Skarels *mp->mscp_addr |= MSCP_OWN | MSCP_INT; 118134293Skarels i = kdbaddr->kdb_ip; 118234293Skarels ki->ki_state = ST_SETCHAR; 118334293Skarels return; 118434293Skarels 118534293Skarels case ST_SETCHAR: 118634293Skarels case ST_RUN: 118734293Skarels /* 118834293Skarels * Handle Set Ctlr Characteristics responses and operational 118934293Skarels * responses (via mscp_dorsp). 119034293Skarels */ 119134293Skarels break; 119234293Skarels 119334293Skarels default: 119434293Skarels log(LOG_ERR, "kdb%d: driver bug, state %d\n", ctlr, 119534293Skarels ki->ki_state); 119634293Skarels return; 119734293Skarels } 119834293Skarels 119934293Skarels if (kdbaddr->kdb_sa & KDB_ERR) {/* ctlr fatal error */ 120034293Skarels kdbsaerror(ki); 120134293Skarels return; 120234293Skarels } 120334293Skarels 120434293Skarels /* 120534293Skarels * Handle buffer purge requests. 120634293Skarels * KDB DOES NOT HAVE BDPs 120734293Skarels */ 120834293Skarels if (ki->ki_ca.ca_bdp) { 120934293Skarels printf("kdb%d: purge bdp %d\n", ctlr, ki->ki_ca.ca_bdp); 121034293Skarels panic("kdb purge"); 121134293Skarels } 121234293Skarels 121334293Skarels /* 121434293Skarels * Check for response and command ring transitions. 121534293Skarels */ 121634293Skarels if (ki->ki_ca.ca_rspint) { 121734293Skarels ki->ki_ca.ca_rspint = 0; 121834293Skarels mscp_dorsp(&ki->ki_mi); 121934293Skarels } 122034293Skarels if (ki->ki_ca.ca_cmdint) { 122134293Skarels ki->ki_ca.ca_cmdint = 0; 122234293Skarels MSCP_DOCMD(&ki->ki_mi); 122334293Skarels } 122434293Skarels if (ki->ki_tab.b_actf != NULL) 122534293Skarels kdbstart(ki); 122634293Skarels } 122734293Skarels 122834293Skarels /* 122934293Skarels * Handle an error datagram. All we do now is decode it. 123034293Skarels */ 123134293Skarels kdbdgram(mi, mp) 123234293Skarels struct mscp_info *mi; 123334293Skarels struct mscp *mp; 123434293Skarels { 123534293Skarels 123634293Skarels mscp_decodeerror(mi->mi_md->md_mname, mi->mi_ctlr, mp); 123734293Skarels } 123834293Skarels 123934293Skarels /* 124034293Skarels * The Set Controller Characteristics command finished. 124134293Skarels * Record the new state of the controller. 124234293Skarels */ 124334293Skarels kdbctlrdone(mi, mp) 124434293Skarels struct mscp_info *mi; 124534293Skarels struct mscp *mp; 124634293Skarels { 124734293Skarels register struct kdbinfo *ki = &kdbinfo[mi->mi_ctlr]; 124834293Skarels 124934293Skarels if ((mp->mscp_status & M_ST_MASK) == M_ST_SUCCESS) 125034293Skarels ki->ki_state = ST_RUN; 125134293Skarels else { 125234293Skarels printf("kdb%d: SETCTLRC failed, status 0x%x\n", 125334293Skarels ki->ki_ctlr, mp->mscp_status); 125434293Skarels ki->ki_state = ST_IDLE; 125534293Skarels } 125634293Skarels if (ki->ki_flags & KDB_DOWAKE) { 125734293Skarels ki->ki_flags &= ~KDB_DOWAKE; 125834757Sbostic wakeup((caddr_t)&ki->ki_flags); 125934293Skarels } 126034293Skarels } 126134293Skarels 126234293Skarels /* 126334293Skarels * Received a response from an as-yet unconfigured drive. Configure it 126434293Skarels * in, if possible. 126534293Skarels */ 126634293Skarels kdbunconf(mi, mp) 126734293Skarels struct mscp_info *mi; 126834293Skarels register struct mscp *mp; 126934293Skarels { 127034293Skarels 127134293Skarels /* 127234293Skarels * If it is a slave response, copy it to kdbslavereply for 127334293Skarels * kdbslave() to look at. 127434293Skarels */ 127534293Skarels if (mp->mscp_opcode == (M_OP_GETUNITST | M_OP_END) && 127634293Skarels (kdbinfo[mi->mi_ctlr].ki_flags & KDB_INSLAVE) != 0) { 127734293Skarels kdbslavereply = *mp; 127834293Skarels return (MSCP_DONE); 127934293Skarels } 128034293Skarels 128134293Skarels /* 128234293Skarels * Otherwise, it had better be an available attention response. 128334293Skarels */ 128434293Skarels if (mp->mscp_opcode != M_OP_AVAILATTN) 128534293Skarels return (MSCP_FAILED); 128634293Skarels 128734293Skarels /* do what autoconf does */ 128834293Skarels return (MSCP_FAILED); /* not yet */ 128934293Skarels } 129034293Skarels 129134293Skarels /* 129234293Skarels * A drive came on line. Check its type and size. Return DONE if 129334293Skarels * we think the drive is truly on line. In any case, awaken anyone 129434293Skarels * sleeping on the drive on-line-ness. 129534293Skarels */ 129634293Skarels kdbonline(ui, mp) 129734293Skarels register struct uba_device *ui; 129834293Skarels struct mscp *mp; 129934293Skarels { 130034293Skarels register int type; 130134293Skarels 130234757Sbostic wakeup((caddr_t)&ui->ui_flags); 130334293Skarels if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) { 130434757Sbostic printf("kdb%d: attempt to bring %s%d on line failed:", 130534293Skarels ui->ui_ctlr, kdbdriver.ud_dname, ui->ui_unit); 130634293Skarels mscp_printevent(mp); 130734293Skarels return (MSCP_FAILED); 130834293Skarels } 130934293Skarels 131034293Skarels type = mp->mscp_onle.onle_drivetype; 131134293Skarels if (type >= NTYPES || kdbtypes[type].ut_name == 0) { 131234293Skarels printf("kdb%d: %s%d: unknown type %d\n", 131334293Skarels ui->ui_ctlr, kdbdriver.ud_dname, ui->ui_unit, type); 131434293Skarels return (MSCP_FAILED); 131534293Skarels } 131634293Skarels /* 131734293Skarels * Note any change of types. Not sure if we should do 131834293Skarels * something special about them, or if so, what.... 131934293Skarels */ 132034293Skarels if (type != ui->ui_type) { 132134293Skarels printf("%s%d: changed types! was %s\n", 132234293Skarels kdbdriver.ud_dname, ui->ui_unit, 132334293Skarels kdbtypes[ui->ui_type].ut_name); 132434293Skarels ui->ui_type = type; 132534293Skarels } 132634293Skarels ra_dsize[ui->ui_unit] = (daddr_t) mp->mscp_onle.onle_unitsize; 132734293Skarels printf("%s%d: %s, size = %d sectors\n", 132834293Skarels kdbdriver.ud_dname, ui->ui_unit, 132934293Skarels kdbtypes[type].ut_name, ra_dsize[ui->ui_unit]); 133034293Skarels return (MSCP_DONE); 133134293Skarels } 133234293Skarels 133334293Skarels /* 133434293Skarels * We got some (configured) unit's status. Return DONE if it succeeded. 133534293Skarels */ 133634293Skarels kdbgotstatus(ui, mp) 133734293Skarels register struct uba_device *ui; 133834293Skarels register struct mscp *mp; 133934293Skarels { 134034293Skarels 134134293Skarels if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) { 134234757Sbostic printf("kdb%d: attempt to get status for %s%d failed:", 134334293Skarels ui->ui_ctlr, kdbdriver.ud_dname, ui->ui_unit); 134434293Skarels mscp_printevent(mp); 134534293Skarels return (MSCP_FAILED); 134634293Skarels } 134734293Skarels /* need to record later for bad block forwarding - for now, print */ 134834293Skarels printf("\ 134934293Skarels %s%d: unit %d, nspt %d, group %d, ngpc %d, rctsize %d, nrpt %d, nrct %d\n", 135034293Skarels kdbdriver.ud_dname, ui->ui_unit, mp->mscp_unit, 135134293Skarels mp->mscp_guse.guse_nspt, mp->mscp_guse.guse_group, 135234293Skarels mp->mscp_guse.guse_ngpc, mp->mscp_guse.guse_rctsize, 135334293Skarels mp->mscp_guse.guse_nrpt, mp->mscp_guse.guse_nrct); 135434293Skarels return (MSCP_DONE); 135534293Skarels } 135634293Skarels 135734293Skarels /* 135834293Skarels * A transfer failed. We get a chance to fix or restart it. 135934293Skarels * Need to write the bad block forwaring code first.... 136034293Skarels */ 136134293Skarels /*ARGSUSED*/ 136234293Skarels kdbioerror(ui, mp, bp) 136334293Skarels register struct uba_device *ui; 136434293Skarels register struct mscp *mp; 136534293Skarels struct buf *bp; 136634293Skarels { 136734293Skarels 136834293Skarels if (mp->mscp_flags & M_EF_BBLKR) { 136934293Skarels /* 137034293Skarels * A bad block report. Eventually we will 137134293Skarels * restart this transfer, but for now, just 137234293Skarels * log it and give up. 137334293Skarels */ 137434293Skarels log(LOG_ERR, "%s%d: bad block report: %d%s\n", 137534293Skarels kdbdriver.ud_dname, ui->ui_unit, mp->mscp_seq.seq_lbn, 137634293Skarels mp->mscp_flags & M_EF_BBLKU ? " + others" : ""); 137734293Skarels } else { 137834293Skarels /* 137934293Skarels * What the heck IS a `serious exception' anyway? 138034293Skarels */ 138134293Skarels if (mp->mscp_flags & M_EF_SEREX) 138234293Skarels log(LOG_ERR, "%s%d: serious exception reported\n", 138334293Skarels kdbdriver.ud_dname, ui->ui_unit); 138434293Skarels } 138534293Skarels return (MSCP_FAILED); 138634293Skarels } 138734293Skarels 138834293Skarels 138934293Skarels #ifdef notyet 139034293Skarels /* 139134293Skarels * I/O controls. Not yet! 139234293Skarels */ 139334293Skarels kdbioctl(dev, cmd, flag, data) 139434293Skarels dev_t dev; 139534293Skarels int cmd, flag; 139634293Skarels caddr_t data; 139734293Skarels { 139834293Skarels int error = 0; 139934293Skarels register int unit = kdbunit(dev); 140034293Skarels 140134293Skarels if (unit >= NKRA || uddinfo[unit] == NULL) 140234293Skarels return (ENXIO); 140334293Skarels 140434293Skarels switch (cmd) { 140534293Skarels 140634293Skarels case KDBIOCREPLACE: 140734293Skarels /* 140834293Skarels * Initiate bad block replacement for the given LBN. 140934293Skarels * (Should we allow modifiers?) 141034293Skarels */ 141134293Skarels error = EOPNOTSUPP; 141234293Skarels break; 141334293Skarels 141434293Skarels case KDBIOCGMICRO: 141534293Skarels /* 141634293Skarels * Return the microcode revision for the KDB50 running 141734293Skarels * this drive. 141834293Skarels */ 141934757Sbostic *(int *)data = kdbinfo[kdbdinfo[unit]->ui_ctlr].ki_micro; 142034293Skarels break; 142134293Skarels 142234293Skarels case KDBIOCGSIZE: 142334293Skarels /* 142434293Skarels * Return the size (in 512 byte blocks) of this 142534293Skarels * disk drive. 142634293Skarels */ 142734757Sbostic *(daddr_t *)data = ra_dsize[unit]; 142834293Skarels break; 142934293Skarels 143034293Skarels default: 143134293Skarels error = EINVAL; 143234293Skarels break; 143334293Skarels } 143434293Skarels return (error); 143534293Skarels } 143634293Skarels #endif 143734293Skarels 143834293Skarels #ifdef notyet 143934293Skarels /* 144034293Skarels * Reset a KDB50 (self test and all). 144134293Skarels * What if it fails? 144234293Skarels */ 144334293Skarels kdbreset(ki) 144434293Skarels register struct kdbinfo *ki; 144534293Skarels { 144634293Skarels 144734293Skarels printf("reset kdb%d", ki->ki_ctlr); 144834293Skarels bi_selftest(&ki->ki_kdb.kdb_bi); 144934293Skarels ki->ki_state = ST_IDLE; 145034293Skarels rminit(ki->ki_map, (long)KI_PTES, (long)1, "kdb", KI_MAPSIZ); 145134293Skarels mscp_requeue(&ki->ki_mi); 145234293Skarels if (kdbinit(ctlr)) 145334293Skarels printf(" (hung)"); 145434293Skarels printf("\n"); 145534293Skarels } 145634293Skarels #endif 145734293Skarels 145834293Skarels /* 145934293Skarels * Watchdog timer: If the controller is active, and no interrupts 146034293Skarels * have occurred for 30 seconds, assume it has gone away. 146134293Skarels */ 146234293Skarels kdbwatch() 146334293Skarels { 146434293Skarels register struct kdbinfo *ki; 146534293Skarels register int i; 146634293Skarels 146734757Sbostic timeout(kdbwatch, (caddr_t)0, hz); /* every second */ 146834293Skarels for (i = 0, ki = kdbinfo; i < NKDB; i++, ki++) { 146934293Skarels if ((ki->ki_flags & KDB_ALIVE) == 0) 147034293Skarels continue; 147134293Skarels if (ki->ki_state == ST_IDLE) 147234293Skarels continue; 147334293Skarels if (ki->ki_state == ST_RUN && !ki->ki_tab.b_active) 147434293Skarels ki->ki_wticks = 0; 147534293Skarels else if (++ki->ki_wticks >= 30) { 147634293Skarels ki->ki_wticks = 0; 147734293Skarels printf("kdb%d: lost interrupt\n", i); 147834293Skarels /* kdbreset(ki); */ 147934293Skarels panic("kdb lost interrupt"); 148034293Skarels } 148134293Skarels } 148234293Skarels } 148334293Skarels 148434293Skarels /* 148534293Skarels * Do a panic dump. 148634293Skarels */ 148734293Skarels #define DBSIZE 32 /* dump 16K at a time */ 148834293Skarels 148934293Skarels struct kdbdumpspace { 149034293Skarels struct kdb1ca kd_ca; 149134293Skarels struct mscp kd_rsp; 149234293Skarels struct mscp kd_cmd; 149334293Skarels } kdbdumpspace; 149434293Skarels 149534293Skarels kdbdump(dev) 149634293Skarels dev_t dev; 149734293Skarels { 149834293Skarels register struct kdbdumpspace *kd; 149934293Skarels register struct kdb_regs *k; 150034293Skarels register int i; 150134293Skarels struct uba_device *ui; 150234293Skarels char *start; 150334293Skarels int num, blk, unit, maxsz, blkoff; 150434293Skarels 150534293Skarels /* 150634293Skarels * Make sure the device is a reasonable place on which to dump. 150734293Skarels */ 150834293Skarels unit = kdbunit(dev); 150934293Skarels if (unit >= NKRA) 151034293Skarels return (ENXIO); 151134293Skarels ui = PHYS(struct uba_device *, kdbdinfo[unit]); 151234293Skarels if (ui == NULL || ui->ui_alive == 0) 151334293Skarels return (ENXIO); 151434293Skarels 151534293Skarels /* 151634293Skarels * Find and initialise the KDB; get the physical address of the 151734293Skarels * device registers, and of communications area and command and 151834293Skarels * response packet. 151934293Skarels */ 152034293Skarels k = PHYS(struct kdbinfo *, &kdbinfo[ui->ui_ctlr])->ki_physkdb; 152134293Skarels kd = PHYS(struct kdbdumpspace *, &kdbdumpspace); 152234293Skarels 152334293Skarels /* 152434293Skarels * Initialise the controller, with one command and one response 152534293Skarels * packet. 152634293Skarels */ 152734293Skarels bi_reset(&k->kdb_bi); 152834293Skarels if (kdbdumpwait(k, KDB_STEP1)) 152934293Skarels return (EFAULT); 153034293Skarels k->kdb_sw = KDB_ERR; 153134293Skarels if (kdbdumpwait(k, KDB_STEP2)) 153234293Skarels return (EFAULT); 153334757Sbostic k->kdb_sw = (int)&kd->kd_ca.ca_rspdsc; 153434293Skarels if (kdbdumpwait(k, KDB_STEP3)) 153534293Skarels return (EFAULT); 153634757Sbostic k->kdb_sw = ((int)&kd->kd_ca.ca_rspdsc) >> 16; 153734293Skarels if (kdbdumpwait(k, KDB_STEP4)) 153834293Skarels return (EFAULT); 153934293Skarels k->kdb_sw = KDB_GO; 154034293Skarels 154134293Skarels /* 154234293Skarels * Set up the command and response descriptor, then set the 154334293Skarels * controller characteristics and bring the drive on line. 154434293Skarels * Note that all uninitialised locations in kd_cmd are zero. 154534293Skarels */ 154634757Sbostic kd->kd_ca.ca_rspdsc = (long)&kd->kd_rsp.mscp_cmdref; 154734757Sbostic kd->kd_ca.ca_cmddsc = (long)&kd->kd_cmd.mscp_cmdref; 154834293Skarels /* kd->kd_cmd.mscp_sccc.sccc_ctlrflags = 0; */ 154934293Skarels /* kd->kd_cmd.mscp_sccc.sccc_version = 0; */ 155034293Skarels if (kdbdumpcmd(M_OP_SETCTLRC, k, kd, ui->ui_ctlr)) 155134293Skarels return (EFAULT); 155234293Skarels kd->kd_cmd.mscp_unit = ui->ui_slave; 155334293Skarels if (kdbdumpcmd(M_OP_ONLINE, k, kd, ui->ui_ctlr)) 155434293Skarels return (EFAULT); 155534293Skarels 155634293Skarels /* 155734293Skarels * Pick up the drive type from the on line end packet; 155834293Skarels * convert that to a dump area size and a disk offset. 155934293Skarels * Note that the assembler uses pc-relative addressing 156034293Skarels * to get at kdbtypes[], no need for PHYS(). 156134293Skarels */ 156234293Skarels i = kd->kd_rsp.mscp_onle.onle_drivetype; 156334293Skarels if (i >= NTYPES || kdbtypes[i].ut_name == 0) { 156434293Skarels printf("disk type %d unknown\ndump "); 156534293Skarels return (EINVAL); 156634293Skarels } 156734293Skarels printf("on %s ", kdbtypes[i].ut_name); 156834293Skarels 156934293Skarels maxsz = kdbtypes[i].ut_sizes[kdbpart(dev)].nblocks; 157034293Skarels blkoff = kdbtypes[i].ut_sizes[kdbpart(dev)].blkoff; 157134293Skarels 157234293Skarels /* 157334293Skarels * Dump all of physical memory, or as much as will fit in the 157434293Skarels * space provided. 157534293Skarels */ 157634293Skarels start = 0; 157734293Skarels num = maxfree; 157834293Skarels if (dumplo < 0) 157934293Skarels return (EINVAL); 158034293Skarels if (dumplo + num >= maxsz) 158134293Skarels num = maxsz - dumplo; 158234293Skarels blkoff += dumplo; 158334293Skarels 158434293Skarels /* 158534293Skarels * Write out memory, DBSIZE pages at a time. 158634293Skarels * N.B.: this code depends on the fact that the sector 158734293Skarels * size == the page size. 158834293Skarels */ 158934293Skarels while (num > 0) { 159034293Skarels blk = num > DBSIZE ? DBSIZE : num; 159134293Skarels kd->kd_cmd.mscp_unit = ui->ui_slave; 159234293Skarels kd->kd_cmd.mscp_seq.seq_lbn = btop(start) + blkoff; 159334293Skarels kd->kd_cmd.mscp_seq.seq_bytecount = blk << PGSHIFT; 159434293Skarels kd->kd_cmd.mscp_seq.seq_buffer = (long)start | KDB_PHYS; 159534293Skarels if (kdbdumpcmd(M_OP_WRITE, k, kd, ui->ui_ctlr)) 159634293Skarels return (EIO); 159734293Skarels start += blk << PGSHIFT; 159834293Skarels num -= blk; 159934293Skarels } 160034293Skarels return (0); /* made it! */ 160134293Skarels } 160234293Skarels 160334293Skarels /* 160434293Skarels * Wait for some of the bits in `bits' to come on. If the error bit 160534293Skarels * comes on, or ten seconds pass without response, return true (error). 160634293Skarels */ 160734293Skarels kdbdumpwait(k, bits) 160834293Skarels register struct kdb_regs *k; 160934293Skarels register int bits; 161034293Skarels { 161134293Skarels register int timo = todr() + 1000; 161234293Skarels 161334293Skarels while ((k->kdb_sa & bits) == 0) { 161434293Skarels if (k->kdb_sa & KDB_ERR) { 161534293Skarels printf("kdb_sa=%b\ndump ", k->kdb_sa, kdbsr_bits); 161634293Skarels return (1); 161734293Skarels } 161834293Skarels if (todr() >= timo) { 161934293Skarels printf("timeout\ndump "); 162034293Skarels return (1); 162134293Skarels } 162234293Skarels } 162334293Skarels return (0); 162434293Skarels } 162534293Skarels 162634293Skarels /* 162734293Skarels * Feed a command to the KDB50, wait for its response, and return 162834293Skarels * true iff something went wrong. 162934293Skarels */ 163034293Skarels kdbdumpcmd(op, k, kd, ctlr) 163134293Skarels int op; 163234293Skarels register struct kdb_regs *k; 163334293Skarels register struct kdbdumpspace *kd; 163434293Skarels int ctlr; 163534293Skarels { 163634293Skarels register int n; 163734293Skarels #define mp (&kd->kd_rsp) 163834293Skarels 163934293Skarels kd->kd_cmd.mscp_opcode = op; 164034293Skarels kd->kd_cmd.mscp_msglen = MSCP_MSGLEN; 164134293Skarels kd->kd_rsp.mscp_msglen = MSCP_MSGLEN; 164234293Skarels kd->kd_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT; 164334293Skarels kd->kd_ca.ca_cmddsc |= MSCP_OWN | MSCP_INT; 164434293Skarels if (k->kdb_sa & KDB_ERR) { 164534293Skarels printf("kdb_sa=%b\ndump ", k->kdb_sa, kdbsr_bits); 164634293Skarels return (1); 164734293Skarels } 164834293Skarels n = k->kdb_ip; 164934293Skarels n = todr() + 1000; 165034293Skarels for (;;) { 165134293Skarels if (todr() > n) { 165234293Skarels printf("timeout\ndump "); 165334293Skarels return (1); 165434293Skarels } 165534293Skarels if (kd->kd_ca.ca_cmdint) 165634293Skarels kd->kd_ca.ca_cmdint = 0; 165734293Skarels if (kd->kd_ca.ca_rspint == 0) 165834293Skarels continue; 165934293Skarels kd->kd_ca.ca_rspint = 0; 166034293Skarels if (mp->mscp_opcode == (op | M_OP_END)) 166134293Skarels break; 166234293Skarels printf("\n"); 166334293Skarels switch (MSCP_MSGTYPE(mp->mscp_msgtc)) { 166434293Skarels 166534293Skarels case MSCPT_SEQ: 166634293Skarels printf("sequential"); 166734293Skarels break; 166834293Skarels 166934293Skarels case MSCPT_DATAGRAM: 167034293Skarels mscp_decodeerror("kdb", ctlr, mp); 167134293Skarels printf("datagram"); 167234293Skarels break; 167334293Skarels 167434293Skarels case MSCPT_CREDITS: 167534293Skarels printf("credits"); 167634293Skarels break; 167734293Skarels 167834293Skarels case MSCPT_MAINTENANCE: 167934293Skarels printf("maintenance"); 168034293Skarels break; 168134293Skarels 168234293Skarels default: 168334293Skarels printf("unknown (type 0x%x)", 168434293Skarels MSCP_MSGTYPE(mp->mscp_msgtc)); 168534293Skarels break; 168634293Skarels } 168734293Skarels printf(" ignored\ndump "); 168834293Skarels kd->kd_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT; 168934293Skarels } 169034293Skarels if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) { 169134293Skarels printf("error: op 0x%x => 0x%x status 0x%x\ndump ", op, 169234293Skarels mp->mscp_opcode, mp->mscp_status); 169334293Skarels return (1); 169434293Skarels } 169534293Skarels return (0); 169634293Skarels #undef mp 169734293Skarels } 169834293Skarels 169934293Skarels /* 170034293Skarels * Return the size of a partition, if known, or -1 if not. 170134293Skarels */ 170234293Skarels kdbsize(dev) 170334293Skarels dev_t dev; 170434293Skarels { 170534293Skarels register int unit = kdbunit(dev); 170634293Skarels register struct uba_device *ui; 170734293Skarels register struct size *st; 170834293Skarels 170934293Skarels if (unit >= NKRA || (ui = kdbdinfo[unit]) == NULL || ui->ui_alive == 0) 171034293Skarels return (-1); 171134293Skarels st = &kdbtypes[ui->ui_type].ut_sizes[kdbpart(dev)]; 171234293Skarels if (st->nblocks == -1) { 171334293Skarels int s = spl5(); 171434293Skarels 171534293Skarels /* 171634293Skarels * We need to have the drive on line to find the size 171734293Skarels * of this particular partition. 171834293Skarels * IS IT OKAY TO GO TO SLEEP IN THIS ROUTINE? 171934293Skarels * (If not, better not page on one of these...) 172034293Skarels */ 172134293Skarels if ((ui->ui_flags & UNIT_ONLINE) == 0) { 172234293Skarels if (kdb_bringonline(ui, 0)) { 172334293Skarels splx(s); 172434293Skarels return (-1); 172534293Skarels } 172634293Skarels } 172734293Skarels splx(s); 172834293Skarels if (st->blkoff > ra_dsize[unit]) 172934293Skarels return (-1); 173034293Skarels return (ra_dsize[unit] - st->blkoff); 173134293Skarels } 173234293Skarels return (st->nblocks); 173334293Skarels } 173434293Skarels 173534293Skarels #endif NKDB > 0 1736