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