1 /* 2 * Copyright (c) 1982, 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)dma.c 7.1 (Berkeley) 05/08/90 8 */ 9 10 /* 11 * DMA driver 12 */ 13 14 #include "param.h" 15 #include "systm.h" 16 #include "time.h" 17 #include "kernel.h" 18 #include "proc.h" 19 #include "dmareg.h" 20 #include "dmavar.h" 21 #include "device.h" 22 23 #include "machine/cpu.h" 24 #include "machine/isr.h" 25 26 extern void isrlink(); 27 extern void printf(); 28 extern void panic(); 29 extern void _insque(); 30 extern void _remque(); 31 extern void timeout(); 32 extern int splbio(); 33 extern void splx(); 34 extern u_int kvtop(); 35 extern void PCIA(); 36 37 /* 38 * The largest single request will be MAXPHYS bytes which will require 39 * at most MAXPHYS/NBPG+1 chain elements to describe, i.e. if none of 40 * the buffer pages are physically contiguous (MAXPHYS/NBPG) and the 41 * buffer is not page aligned (+1). 42 */ 43 #define DMAMAXIO (MAXPHYS/NBPG+1) 44 45 #define DMATIMO 15 46 47 struct dma_softc { 48 struct dmadevice *sc_hwaddr; 49 struct dmaBdevice *sc_Bhwaddr; 50 int sc_type; 51 int sc_cur; 52 int sc_cmd; 53 int sc_timo; 54 int sc_count[DMAMAXIO+1]; 55 char *sc_addr[DMAMAXIO+1]; 56 } dma_softc[NDMA]; 57 58 /* types */ 59 #define DMA_B 0 60 #define DMA_C 1 61 62 struct devqueue dmachan[NDMA + 1]; 63 int dmaintr(); 64 void dmatimo(); 65 66 #ifdef DEBUG 67 int dmadebug = 0; 68 #define DDB_WORD 0x01 /* same as DMAGO_WORD */ 69 #define DDB_LWORD 0x02 /* same as DMAGO_LWORD */ 70 #define DDB_FOLLOW 0x04 71 #define DDB_IO 0x08 72 73 long dmahits[NDMA]; 74 long dmamisses[NDMA]; 75 long dmabyte[NDMA]; 76 long dmaword[NDMA]; 77 long dmalword[NDMA]; 78 #endif 79 80 void 81 dmainit() 82 { 83 register struct dmareg *dma = (struct dmareg *)DMA_BASE; 84 register struct dma_softc *dc; 85 register int i; 86 char rev; 87 88 /* 89 * Determine the DMA type. 90 * Don't know how to easily differentiate the A and B cards, 91 * so we just hope nobody has an A card (A cards will work if 92 * DMAINTLVL is set to 3). 93 */ 94 if (!badbaddr((char *)&dma->dma_id[2])) 95 rev = dma->dma_id[2]; 96 else { 97 rev = 'B'; 98 #if !defined(HP320) 99 panic("dmainit: DMA card requires hp320 support"); 100 #endif 101 } 102 103 dc = &dma_softc[0]; 104 for (i = 0; i < NDMA; i++) { 105 dc->sc_hwaddr = (i & 1) ? &dma->dma_chan1 : &dma->dma_chan0; 106 dc->sc_Bhwaddr = (i & 1) ? &dma->dma_Bchan1 : &dma->dma_Bchan0; 107 dc->sc_type = rev == 'B' ? DMA_B : DMA_C; 108 dc++; 109 dmachan[i].dq_forw = dmachan[i].dq_back = &dmachan[i]; 110 } 111 dmachan[i].dq_forw = dmachan[i].dq_back = &dmachan[i]; 112 timeout(dmatimo, (caddr_t)0, DMATIMO * hz); 113 114 printf("dma: 98620%c with 2 channels, %d bit DMA\n", 115 rev, rev == 'B' ? 16 : 32); 116 } 117 118 int 119 dmareq(dq) 120 register struct devqueue *dq; 121 { 122 register int i; 123 register int chan; 124 register int s = splbio(); 125 126 chan = dq->dq_ctlr; 127 i = NDMA; 128 while (--i >= 0) { 129 if ((chan & (1 << i)) == 0) 130 continue; 131 if (dmachan[i].dq_forw != &dmachan[i]) 132 continue; 133 insque(dq, &dmachan[i]); 134 dq->dq_ctlr = i; 135 splx(s); 136 return(1); 137 } 138 insque(dq, dmachan[NDMA].dq_back); 139 splx(s); 140 return(0); 141 } 142 143 void 144 dmafree(dq) 145 register struct devqueue *dq; 146 { 147 int unit = dq->dq_ctlr; 148 register struct dma_softc *dc = &dma_softc[unit]; 149 register struct devqueue *dn; 150 register int chan, s; 151 152 s = splbio(); 153 dc->sc_timo = 0; 154 DMA_CLEAR(dc); 155 remque(dq); 156 chan = 1 << unit; 157 for (dn = dmachan[NDMA].dq_forw; 158 dn != &dmachan[NDMA]; dn = dn->dq_forw) { 159 if (dn->dq_ctlr & chan) { 160 remque((caddr_t)dn); 161 insque((caddr_t)dn, (caddr_t)dq->dq_back); 162 splx(s); 163 dn->dq_ctlr = dq->dq_ctlr; 164 (dn->dq_driver->d_start)(dn->dq_unit); 165 return; 166 } 167 } 168 splx(s); 169 } 170 171 void 172 dmago(unit, addr, count, flags) 173 int unit; 174 register char *addr; 175 register int count; 176 register int flags; 177 { 178 register struct dma_softc *dc = &dma_softc[unit]; 179 register char *dmaend = NULL; 180 register int tcount, i; 181 182 #ifdef DEBUG 183 if (dmadebug & DDB_FOLLOW) 184 printf("dmago(%d, %x, %x, %x)\n", 185 unit, addr, count, flags); 186 if (flags & DMAGO_LWORD) 187 dmalword[unit]++; 188 else if (flags & DMAGO_WORD) 189 dmaword[unit]++; 190 else 191 dmabyte[unit]++; 192 #endif 193 #if defined(HP320) 194 if (dc->sc_type == DMA_B && (flags & DMAGO_LWORD)) 195 panic("dmago: no can do 32-bit DMA"); 196 #endif 197 /* 198 * Build the DMA chain 199 */ 200 for (i = 0; i < DMAMAXIO && count; i++) { 201 dc->sc_addr[i] = (char *)kvtop(addr); 202 tcount = dc->sc_count[i] = 203 MIN(count, NBPG - ((int)addr & PGOFSET)); 204 addr += dc->sc_count[i]; 205 count -= tcount; 206 if (flags & (DMAGO_WORD|DMAGO_LWORD)) 207 tcount >>= (flags & DMAGO_WORD) ? 1 : 2; 208 if (dc->sc_addr[i] == dmaend 209 #if defined(HP320) 210 /* only 16-bit count on 98620B */ 211 && (dc->sc_type != DMA_B || 212 dc->sc_count[i-1] + tcount <= 65536) 213 #endif 214 ) { 215 #ifdef DEBUG 216 dmahits[unit]++; 217 #endif 218 dmaend += dc->sc_count[i]; 219 dc->sc_count[i-1] += tcount; 220 i--; 221 } else { 222 #ifdef DEBUG 223 dmamisses[unit]++; 224 #endif 225 dmaend = dc->sc_addr[i] + dc->sc_count[i]; 226 dc->sc_count[i] = tcount; 227 } 228 } 229 if (count) 230 panic("dmago maxphys"); 231 dc->sc_count[i] = 0; 232 dc->sc_cur = 0; 233 /* 234 * Set up the command word based on flags 235 */ 236 dc->sc_cmd = DMA_ENAB | DMA_IPL(DMAINTLVL) | DMA_START; 237 if ((flags & DMAGO_READ) == 0) 238 dc->sc_cmd |= DMA_WRT; 239 if (flags & DMAGO_LWORD) 240 dc->sc_cmd |= DMA_LWORD; 241 else if (flags & DMAGO_WORD) 242 dc->sc_cmd |= DMA_WORD; 243 if (flags & DMAGO_PRI) 244 dc->sc_cmd |= DMA_PRI; 245 246 /* 247 * We should be able to skip the dma completion interrupt 248 * if we only have one segment in the chain since many 249 * devices generate their own completion interrupt. 250 * However, on a 370 we have to take the interrupt on 251 * read transfers to invalidate the external cache. 252 */ 253 if ((flags & DMAGO_NOINT) && i == 1 254 #if defined(HP370) 255 && ((flags & DMAGO_READ) == 0 || ectype != EC_PHYS) 256 #endif 257 ) 258 dc->sc_cmd &= ~DMA_ENAB; 259 #ifdef DEBUG 260 #if defined(HP320) 261 /* would this hurt? */ 262 if (dc->sc_type == DMA_B) 263 dc->sc_cmd &= ~DMA_START; 264 #endif 265 if (dmadebug & DDB_IO) 266 if ((dmadebug&DDB_WORD) && (dc->sc_cmd&DMA_WORD) || 267 (dmadebug&DDB_LWORD) && (dc->sc_cmd&DMA_LWORD)) { 268 printf("dmago: cmd %x\n", dc->sc_cmd); 269 for (i = 0; dc->sc_count[i]; i++) 270 printf(" %d: %d@%x\n", 271 i, dc->sc_count[i], dc->sc_addr[i]); 272 } 273 #endif 274 275 /* 276 * Load and arm the channel 277 */ 278 dc->sc_timo = 1; 279 DMA_ARM(dc, 0); 280 } 281 282 void 283 dmastop(unit) 284 register int unit; 285 { 286 register struct dma_softc *dc = &dma_softc[unit]; 287 register struct devqueue *dq; 288 289 #ifdef DEBUG 290 if (dmadebug & DDB_FOLLOW) 291 printf("dmastop(%d)\n", unit); 292 #endif 293 dc->sc_timo = 0; 294 DMA_CLEAR(dc); 295 296 /* 297 * We may get this interrupt after a device service routine 298 * has freed the dma channel. So, ignore the intr if there's 299 * nothing on the queue. 300 */ 301 dq = dmachan[unit].dq_forw; 302 if (dq != &dmachan[unit]) { 303 #if defined(HP370) 304 /* 305 * The 370 has an 64k external physical address cache. 306 * In theory, we should only need to flush it when 307 * DMAing to memory. 308 */ 309 if (ectype == EC_PHYS && (dc->sc_cmd & DMA_WRT) == 0) 310 PCIA(); 311 #endif 312 (dq->dq_driver->d_done)(dq->dq_unit); 313 } 314 } 315 316 int 317 dmaintr() 318 { 319 register struct dma_softc *dc; 320 register int i, j, stat; 321 int found = 0; 322 323 #ifdef DEBUG 324 if (dmadebug & DDB_FOLLOW) 325 printf("dmaintr\n"); 326 #endif 327 for (i = 0, dc = dma_softc; i < NDMA; i++, dc++) { 328 stat = DMA_STAT(dc); 329 if ((stat & DMA_INTR) == 0) 330 continue; 331 found++; 332 #ifdef DEBUG 333 if (dmadebug & DDB_IO) { 334 if ((dmadebug&DDB_WORD) && (dc->sc_cmd&DMA_WORD) || 335 (dmadebug&DDB_LWORD) && (dc->sc_cmd&DMA_LWORD)) 336 printf("dmaintr: unit %d stat %x next %d\n", 337 i, stat, dc->sc_cur+1); 338 } 339 if (stat & DMA_ARMED) 340 printf("dma%d: intr when armed\n", i); 341 #endif 342 j = ++dc->sc_cur; 343 if (j < DMAMAXIO && dc->sc_count[j]) { 344 dc->sc_timo = 1; 345 DMA_CLEAR(dc); 346 DMA_ARM(dc, j); 347 } else 348 dmastop(i); 349 } 350 return(found); 351 } 352 353 void 354 dmatimo() 355 { 356 register int i, s; 357 register struct dma_softc *dc = &dma_softc[0]; 358 359 for (i = 0; i < NDMA; i++, dc++) { 360 s = splbio(); 361 if (dc->sc_timo) { 362 if (dc->sc_timo == 1) 363 dc->sc_timo++; 364 else 365 dmastop(i); 366 } 367 splx(s); 368 } 369 timeout(dmatimo, (caddr_t)0, DMATIMO * hz); 370 } 371