1 /* 2 * Copyright (c) 1982 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)mba.c 7.5 (Berkeley) 12/16/90 7 */ 8 9 #include "mba.h" 10 #if NMBA > 0 11 /* 12 * Massbus driver, arbitrates a massbus among attached devices. 13 */ 14 #include "../include/pte.h" 15 16 #include "sys/param.h" 17 #include "sys/systm.h" 18 #include "sys/dkstat.h" 19 #include "sys/buf.h" 20 #include "sys/conf.h" 21 #include "sys/user.h" 22 #include "sys/proc.h" 23 #include "sys/map.h" 24 #include "../include/mtpr.h" 25 #include "sys/vm.h" 26 27 #include "mbareg.h" 28 #include "mbavar.h" 29 30 /* mbunit should be the same as hpunit, etc.! */ 31 #define mbunit(dev) (minor(dev) >> 3) 32 33 char mbsr_bits[] = MBSR_BITS; 34 /* 35 * Start activity on a massbus device. 36 * We are given the device's mba_device structure and activate 37 * the device via the unit start routine. The unit start 38 * routine may indicate that it is finished (e.g. if the operation 39 * was a ``sense'' on a tape drive), that the (multi-ported) unit 40 * is busy (we will get an interrupt later), that it started the 41 * unit (e.g. for a non-data transfer operation), or that it has 42 * set up a data transfer operation and we should start the massbus adaptor. 43 */ 44 mbustart(mi) 45 register struct mba_device *mi; 46 { 47 register struct buf *bp; /* i/o operation at head of queue */ 48 register struct mba_hd *mhp; /* header for mba device is on */ 49 50 loop: 51 /* 52 * Get the first thing to do off device queue. 53 */ 54 bp = mi->mi_tab.b_actf; 55 if (bp == NULL) 56 return; 57 /* 58 * Let the drivers unit start routine have at it 59 * and then process the request further, per its instructions. 60 */ 61 switch ((*mi->mi_driver->md_ustart)(mi)) { 62 63 case MBU_NEXT: /* request is complete (e.g. ``sense'') */ 64 mi->mi_tab.b_active = 0; 65 mi->mi_tab.b_errcnt = 0; 66 mi->mi_tab.b_actf = bp->av_forw; 67 biodone(bp); 68 goto loop; 69 70 case MBU_DODATA: /* all ready to do data transfer */ 71 /* 72 * Queue the device mba_device structure on the massbus 73 * mba_hd structure for processing as soon as the 74 * data path is available. 75 */ 76 mhp = mi->mi_hd; 77 mi->mi_forw = NULL; 78 if (mhp->mh_actf == NULL) 79 mhp->mh_actf = mi; 80 else 81 mhp->mh_actl->mi_forw = mi; 82 mhp->mh_actl = mi; 83 /* 84 * If data path is idle, start transfer now. 85 * In any case the device is ``active'' waiting for the 86 * data to transfer. 87 */ 88 mi->mi_tab.b_active = 1; 89 if (mhp->mh_active == 0) 90 mbstart(mhp); 91 return; 92 93 case MBU_STARTED: /* driver started a non-data transfer */ 94 /* 95 * Mark device busy during non-data transfer 96 * and count this as a ``seek'' on the device. 97 */ 98 if (mi->mi_dk >= 0) { 99 dk_seek[mi->mi_dk]++; 100 dk_busy |= (1 << mi->mi_dk); 101 } 102 mi->mi_tab.b_active = 1; 103 return; 104 105 case MBU_BUSY: /* dual port drive busy */ 106 /* 107 * We mark the device structure so that when an 108 * interrupt occurs we will know to restart the unit. 109 */ 110 mi->mi_tab.b_flags |= B_BUSY; 111 return; 112 113 default: 114 panic("mbustart"); 115 } 116 } 117 118 /* 119 * Start an i/o operation on the massbus specified by the argument. 120 * We peel the first operation off its queue and insure that the drive 121 * is present and on-line. We then use the drivers start routine 122 * (if any) to prepare the drive, setup the massbus map for the transfer 123 * and start the transfer. 124 */ 125 mbstart(mhp) 126 register struct mba_hd *mhp; 127 { 128 register struct mba_device *mi; 129 struct buf *bp; 130 register struct mba_regs *mbp; 131 register int com; 132 extern int cold; 133 134 loop: 135 /* 136 * Look for an operation at the front of the queue. 137 */ 138 if ((mi = mhp->mh_actf) == NULL) { 139 return; 140 } 141 if ((bp = mi->mi_tab.b_actf) == NULL) { 142 mhp->mh_actf = mi->mi_forw; 143 goto loop; 144 } 145 /* 146 * If this device isn't present and on-line, then 147 * we screwed up, and can't really do the operation. 148 * Only check for non-tapes because tape drivers check 149 * ONLINE themselves and because TU78 registers are 150 * different. 151 * No complaints during autoconfiguration, 152 * when we try to read disk labels from anything on line. 153 */ 154 if (((com = mi->mi_drv->mbd_dt) & MBDT_TAP) == 0) 155 if ((mi->mi_drv->mbd_ds & MBDS_DREADY) != MBDS_DREADY) { 156 if (!cold) { 157 if ((com & MBDT_TYPE) == 0) { 158 mi->mi_alive = 0; 159 printf("%s%d: nonexistent\n", mi->mi_driver->md_dname, 160 mbunit(bp->b_dev)); 161 } else 162 printf("%s%d: not ready\n", mi->mi_driver->md_dname, 163 mbunit(bp->b_dev)); 164 } 165 mi->mi_tab.b_actf = bp->av_forw; 166 mi->mi_tab.b_errcnt = 0; 167 mi->mi_tab.b_active = 0; 168 bp->b_flags |= B_ERROR; 169 biodone(bp); 170 goto loop; 171 } 172 /* 173 * We can do the operation; mark the massbus active 174 * and let the device start routine setup any necessary 175 * device state for the transfer (e.g. desired cylinder, etc 176 * on disks). 177 */ 178 mhp->mh_active = 1; 179 if (mi->mi_driver->md_start == (int (*)())0 || 180 (com = (*mi->mi_driver->md_start)(mi)) == 0) 181 com = (bp->b_flags & B_READ) ? MB_RCOM|MB_GO : MB_WCOM|MB_GO; 182 183 /* 184 * Setup the massbus control and map registers and start 185 * the transfer. 186 */ 187 mbp = mi->mi_mba; 188 mbp->mba_sr = -1; /* conservative */ 189 if (bp->b_bcount >= 0) { 190 mbp->mba_var = mbasetup(mi) + mi->mi_tab.b_bdone; 191 mbp->mba_bcr = -(bp->b_bcount - mi->mi_tab.b_bdone); 192 } else { 193 mbp->mba_var = mbasetup(mi) - bp->b_bcount - mi->mi_tab.b_bdone - 1; 194 mbp->mba_bcr = bp->b_bcount + mi->mi_tab.b_bdone; 195 } 196 mi->mi_drv->mbd_cs1 = com; 197 if (mi->mi_dk >= 0) { 198 dk_busy |= 1 << mi->mi_dk; 199 dk_xfer[mi->mi_dk]++; 200 if (bp->b_bcount >= 0) 201 dk_wds[mi->mi_dk] += bp->b_bcount >> 6; 202 else 203 dk_wds[mi->mi_dk] += -(bp->b_bcount) >> 6; 204 } 205 } 206 207 /* 208 * Take an interrupt off of massbus mbanum, 209 * and dispatch to drivers as appropriate. 210 */ 211 mbintr(mbanum) 212 int mbanum; 213 { 214 register struct mba_hd *mhp = &mba_hd[mbanum]; 215 register struct mba_regs *mbp = mhp->mh_mba; 216 register struct mba_device *mi; 217 register struct buf *bp; 218 register int drive; 219 int mbasr, as; 220 extern struct mba_device *mbaconfig(); 221 222 /* 223 * Read out the massbus status register 224 * and attention status register and clear 225 * the bits in same by writing them back. 226 */ 227 mbasr = mbp->mba_sr; 228 mbp->mba_sr = mbasr; 229 #if VAX750 230 if (mbasr&MBSR_CBHUNG) { 231 printf("mba%d: control bus hung\n", mbanum); 232 panic("cbhung"); 233 } 234 #endif 235 /* note: the mbd_as register is shared between drives */ 236 as = mbp->mba_drv[0].mbd_as & 0xff; 237 mbp->mba_drv[0].mbd_as = as; 238 239 /* 240 * If the mba was active, process the data transfer 241 * complete interrupt; otherwise just process units which 242 * are now finished. 243 */ 244 if (mhp->mh_active) { 245 /* 246 * Clear attention status for drive whose data 247 * transfer related operation completed, 248 * and give the dtint driver 249 * routine a chance to say what is next. 250 */ 251 mi = mhp->mh_actf; 252 as &= ~(1 << mi->mi_drive); 253 dk_busy &= ~(1 << mi->mi_dk); 254 bp = mi->mi_tab.b_actf; 255 switch ((*mi->mi_driver->md_dtint)(mi, mbasr)) { 256 257 case MBD_DONE: /* all done, for better or worse */ 258 /* 259 * Flush request from drive queue. 260 */ 261 mi->mi_tab.b_errcnt = 0; 262 mi->mi_tab.b_actf = bp->av_forw; 263 biodone(bp); 264 /* fall into... */ 265 case MBD_RETRY: /* attempt the operation again */ 266 /* 267 * Dequeue data transfer from massbus queue; 268 * if there is still a i/o request on the device 269 * queue then start the next operation on the device. 270 * (Common code for DONE and RETRY). 271 */ 272 mhp->mh_active = 0; 273 mi->mi_tab.b_active = 0; 274 mhp->mh_actf = mi->mi_forw; 275 if (mi->mi_tab.b_actf) 276 mbustart(mi); 277 break; 278 279 case MBD_REPOSITION: /* driver started repositioning */ 280 /* 281 * Drive is repositioning, not doing data transfer. 282 * Free controller, but don't have to restart drive. 283 */ 284 mhp->mh_active = 0; 285 mhp->mh_actf = mi->mi_forw; 286 break; 287 288 case MBD_RESTARTED: /* driver restarted op (ecc, e.g.) */ 289 /* 290 * Note that mhp->mh_active is still on. 291 */ 292 break; 293 294 default: 295 panic("mbintr"); 296 } 297 } 298 /* 299 * Service drives which require attention 300 * after non-data-transfer operations. 301 */ 302 while (drive = ffs((long)as)) { 303 drive--; /* was 1 origin */ 304 as &= ~(1 << drive); 305 mi = mhp->mh_mbip[drive]; 306 if (mi == NULL || mi->mi_alive == 0) { 307 struct mba_device fnd; 308 struct mba_drv *mbd = &mhp->mh_mba->mba_drv[drive]; 309 int dt = mbd->mbd_dt & 0xffff; 310 311 if (dt == 0 || dt == MBDT_MOH) 312 continue; 313 fnd.mi_mba = mhp->mh_mba; 314 fnd.mi_mbanum = mbanum; 315 fnd.mi_drive = drive; 316 if ((mi = mbaconfig(&fnd, dt)) == NULL) 317 continue; 318 /* 319 * If a tape, poke the slave attach routines. 320 * Otherwise, could be a disk which we want 321 * to swap on, so make a pass over the swap 322 * configuration table in case the size of 323 * the swap area must be determined by drive type. 324 */ 325 if (dt & MBDT_TAP) 326 mbaddtape(mi, drive); 327 else 328 swapconf(); 329 } 330 /* 331 * If driver has a handler for non-data transfer 332 * interrupts, give it a chance to tell us what to do. 333 */ 334 if (mi->mi_driver->md_ndint) { 335 switch ((*mi->mi_driver->md_ndint)(mi)) { 336 337 case MBN_DONE: /* operation completed */ 338 mi->mi_tab.b_active = 0; 339 mi->mi_tab.b_errcnt = 0; 340 bp = mi->mi_tab.b_actf; 341 mi->mi_tab.b_actf = bp->av_forw; 342 biodone(bp); 343 /* fall into common code */ 344 case MBN_RETRY: /* operation continues */ 345 if (mi->mi_tab.b_actf) 346 mbustart(mi); 347 break; 348 case MBN_SKIP: /* ignore unsol. interrupt */ 349 break; 350 default: 351 panic("mbintr"); 352 } 353 } else 354 /* 355 * If there is no non-data transfer interrupt 356 * routine, then we should just 357 * restart the unit, leading to a mbstart() soon. 358 */ 359 mbustart(mi); 360 } 361 /* 362 * If there is an operation available and 363 * the massbus isn't active, get it going. 364 */ 365 if (mhp->mh_actf && !mhp->mh_active) 366 mbstart(mhp); 367 /* THHHHATS all folks... */ 368 } 369 370 /* 371 * For autoconfig'ng tape drives on the fly. 372 */ 373 mbaddtape(mi, drive) 374 struct mba_device *mi; 375 int drive; 376 { 377 register struct mba_slave *ms; 378 379 for (ms = mbsinit; ms->ms_driver; ms++) 380 if (ms->ms_driver == mi->mi_driver && ms->ms_alive == 0 && 381 (ms->ms_ctlr == mi->mi_unit || 382 ms->ms_ctlr == '?')) { 383 if ((*ms->ms_driver->md_slave)(mi, ms, drive)) { 384 printf("%s%d at %s%d slave %d\n", 385 ms->ms_driver->md_sname, 386 ms->ms_unit, 387 mi->mi_driver->md_dname, 388 mi->mi_unit, 389 ms->ms_slave); 390 ms->ms_alive = 1; 391 ms->ms_ctlr = mi->mi_unit; 392 } 393 } 394 } 395 396 /* 397 * Setup the mapping registers for a transfer. 398 */ 399 mbasetup(mi) 400 register struct mba_device *mi; 401 { 402 register struct mba_regs *mbap = mi->mi_mba; 403 struct buf *bp = mi->mi_tab.b_actf; 404 register int npf; 405 unsigned v; 406 register struct pte *pte, *io; 407 int o; 408 struct proc *rp; 409 410 v = btop(bp->b_un.b_addr); 411 o = (int)(bp->b_un.b_addr) & PGOFSET; 412 if (bp->b_bcount >= 0) 413 npf = btoc(bp->b_bcount + o); 414 else 415 npf = btoc(-(bp->b_bcount) + o); 416 rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc; 417 if ((bp->b_flags & B_PHYS) == 0) 418 pte = &Sysmap[btop(((int)bp->b_un.b_addr)&0x7fffffff)]; 419 else if (bp->b_flags & B_UAREA) 420 pte = &rp->p_addr[v]; 421 else if (bp->b_flags & B_PAGET) 422 pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)]; 423 else 424 pte = vtopte(rp, v); 425 io = mbap->mba_map; 426 while (--npf >= 0) { 427 if (pte->pg_pfnum == 0) 428 panic("mba, zero entry"); 429 *(int *)io++ = pte++->pg_pfnum | PG_V; 430 } 431 *(int *)io++ = 0; 432 return (o); 433 } 434 435 #if notdef 436 /* 437 * Init and interrupt enable a massbus adapter. 438 */ 439 mbainit(mp) 440 struct mba_regs *mp; 441 { 442 443 mp->mba_cr = MBCR_INIT; 444 mp->mba_cr = MBCR_IE; 445 } 446 #endif 447 #endif 448