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