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