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