1 /* 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. 7 * 8 * %sccs.include.redist.c% 9 * 10 * from: $Hdr: iop.c,v 4.300 91/06/09 06:42:37 root Rel41 $ SONY 11 * 12 * @(#)iop.c 7.2 (Berkeley) 12/17/92 13 */ 14 15 /* 16 * iop.c / hb.c ver 0.0 17 */ 18 19 #include <machine/fix_machine_type.h> 20 #include <machine/machConst.h> 21 22 #include <sys/param.h> 23 #include <sys/systm.h> 24 #include <sys/map.h> 25 #include <sys/buf.h> 26 #include <sys/proc.h> 27 #include <sys/user.h> 28 #include <sys/conf.h> 29 #include <sys/dkstat.h> 30 #include <sys/kernel.h> 31 #include <sys/malloc.h> 32 33 #include <machine/pte.h> 34 #include <machine/cpu.h> 35 36 #ifndef news700 37 38 #include <news3400/iodev/scsireg.h> 39 40 #ifdef CPU_DOUBLE 41 #include "../iop/iopvar.h" 42 #endif 43 44 #ifdef CPU_SINGLE 45 #include <news3400/hbdev/hbvar.h> 46 #include <news3400/hbdev/scsic.h> 47 struct scsi_stat scsi_stat; 48 #endif 49 50 /* 51 * dual processor ===> single processor 52 */ 53 #ifdef CPU_SINGLE 54 # define iopreset hbreset 55 # define iopbuf hbbuf 56 # define iopalloc hballoc 57 # define iopsetup hbsetup 58 # define iop_ctlr hb_ctlr 59 # define iop_device hb_device 60 # define iopgo hbgo 61 62 # define im_driver hm_driver 63 # define im_ctlr hm_ctlr 64 # define im_alive hm_alive 65 # define im_addr hm_addr 66 # define im_intr hm_intr 67 # define im_scnum hm_scnum 68 # define im_hd hm_hd 69 # define im_hbinfo hm_hbinfo 70 # define im_tab hm_tab 71 72 # define ii_driver hi_driver 73 # define ii_unit hi_unit 74 # define ii_ctlr hi_ctlr 75 # define ii_slave hi_slave 76 # define ii_addr hi_addr 77 # define ii_intr hi_intr 78 # define ii_dk hi_dk 79 # define ii_flags hi_flags 80 # define ii_alive hi_alive 81 # define ii_type hi_type 82 # define ii_forw hi_forw 83 # define ii_mi hi_mi 84 # define ii_hd hi_hd 85 86 # define id_dgo hd_dgo 87 #endif /* CPU_SINGLE */ 88 89 iopgo(ii, map) 90 register struct iop_device *ii; 91 struct sc_map *map; 92 { 93 register struct iop_ctlr *im = ii->ii_mi; 94 register int unit; 95 int s; 96 97 #ifdef PMAXSPL 98 s = Mach_spl3(); 99 #else 100 s = spl6(); 101 #endif 102 if (map) 103 (void)iopsetup(im->im_tab.b_actf->b_actf, map, NSCMAP); 104 splx(s); 105 if (ii->ii_dk >= 0) { 106 unit = ii->ii_dk; 107 dk_busy |= 1<<unit; 108 dk_xfer[unit]++; 109 dk_wds[unit] += im->im_tab.b_actf->b_actf->b_bcount>>6; 110 } 111 if (im->im_driver->id_dgo) 112 (*im->im_driver->id_dgo)(im); 113 } 114 115 iopsetup(bp, map, nmap) 116 register struct buf *bp; 117 struct sc_map *map; 118 int nmap; 119 { 120 register struct pte *pte; 121 register unsigned *io; 122 int o, npf; 123 124 o = (int)bp->b_un.b_addr & PGOFSET; 125 map->mp_offset = o; 126 npf = btoc(bp->b_bcount + o); 127 if (npf > nmap) 128 panic("sc_map setup: bcount too large"); 129 map->mp_pages = npf; 130 io = map->mp_addr; 131 #ifdef mips 132 if (MACH_IS_UNMAPPED(bp->b_un.b_addr)) { 133 int i; 134 135 for (i = 0; npf-- > 0; i++) 136 *io++ = ((MACH_UNMAPPED_TO_PHYS(bp->b_un.b_addr)) 137 >> PGSHIFT) + i; 138 return (1); 139 } 140 else if ((bp->b_un.b_addr >= (caddr_t)VM_MIN_KERNEL_ADDRESS) && 141 (bp->b_un.b_addr < (caddr_t)VM_MAX_KERNEL_ADDRESS)) { 142 pte = (struct pte*)kvtopte(bp->b_un.b_addr); 143 while (--npf >= 0) { 144 if (pte->pg_pfnum == 0) 145 panic("sc_map setup: zero pfnum"); 146 *io++ = pte++->pg_pfnum; 147 } 148 return (1); 149 } 150 else { 151 panic("iopsetup: user address is not allowed"); 152 } 153 #else /* mips */ 154 ERROR! This code doesn't work. /* KU:XXX */ 155 pte = buftopte(bp); 156 while (--npf >= 0) { 157 if (pte->pg_pfnum == 0) 158 panic("sc_map setup: zero pfnum"); 159 *io++ = pte++->pg_pfnum; 160 } 161 return (1); 162 #endif /* mips */ 163 } 164 165 iopalloc(addr, bcnt, map, nmap) 166 caddr_t addr; 167 int bcnt, nmap; 168 struct sc_map *map; 169 { 170 struct buf iopbuf; 171 172 iopbuf.b_un.b_addr = addr; 173 iopbuf.b_flags = B_BUSY; 174 iopbuf.b_bcount = bcnt; 175 /* that's all the fields iopsetup() needs */ 176 return (iopsetup(&iopbuf, map, nmap)); 177 } 178 179 iopreset() 180 { 181 register struct cdevsw *cdp; 182 int s; 183 184 #ifdef CPU_DOUBLE 185 s = spl6(); 186 printf("iop: reset"); 187 for (cdp = cdevsw; cdp < cdevsw + nchrdev; cdp++) 188 (*cdp->d_reset)(); 189 printf("\n"); 190 splx(s); 191 #endif 192 #ifdef CPU_SINGLE 193 printf("hb: reset"); 194 for (cdp = cdevsw; cdp < cdevsw + nchrdev; cdp++) 195 (*cdp->d_reset)(); 196 printf("\n"); 197 #endif 198 } 199 200 #ifdef CPU_SINGLE 201 scsend(chan, flag, sc) 202 int chan; 203 int flag; 204 struct scsi *sc; 205 { 206 register int i; 207 208 sc_send(chan, flag, sc); 209 if (flag & SCSI_NOTWAIT) 210 return; 211 if ((flag & SCSI_INTEN) == 0) { 212 for (i = 0; i < 2000000; i++) 213 if (!sc_busy(chan)) 214 return; 215 printf("SCSI: scsend() timeout: intr=0x%x, ie=0x%x, sc=0x%x\n", 216 chan, flag, sc); 217 } 218 } 219 #endif /* CPU_SINGLE */ 220 221 #endif /* !news700 */ 222 223 #ifdef CPU_SINGLE 224 /*kos000*/ 225 int 226 on_iobusintr2(func, arg, pri) 227 int (*func)(); 228 int arg; 229 int pri; 230 { 231 register_hb_intr2(func, arg, pri); 232 } 233 234 int 235 on_iobusintr4(func, arg, pri) 236 int (*func)(); 237 int arg; 238 int pri; 239 { 240 register_hb_intr4(func, arg, pri); 241 } 242 /*kos000*/ 243 244 /*kos111*/ 245 struct hb_intr { 246 struct hb_intr *forw; 247 struct hb_intr *back; 248 int pri; 249 int (*func)(); 250 int arg; 251 }; 252 253 struct hb_intr hb_intr2; 254 struct hb_intr hb_intr4; 255 256 init_hb_intr() 257 { 258 init_hb_intr2(); 259 init_hb_intr4(); 260 } 261 262 init_hb_intr2() 263 { 264 hb_intr2.forw = hb_intr2.back = &hb_intr2; 265 hb_intr2.pri = 32767; 266 hb_intr2.func = 0; 267 hb_intr2.arg = 0; 268 } 269 270 init_hb_intr4() 271 { 272 hb_intr4.forw = hb_intr4.back = &hb_intr4; 273 hb_intr4.pri = 32767; 274 hb_intr4.func = 0; 275 hb_intr4.arg = 0; 276 } 277 278 register_hb_intr2(func, arg, pri) 279 int (*func)(); 280 int arg; 281 int pri; 282 { 283 register struct hb_intr *p, *q; 284 register int s = splclock(); 285 286 p = malloc(sizeof (struct hb_intr), M_DEVBUF, M_WAITOK); 287 p->pri = pri; 288 p->func = func; 289 p->arg = arg; 290 291 for (q = hb_intr2.forw; q != &hb_intr2; q = q->forw) 292 if (p->pri < q->pri) 293 break; 294 insque(p, q->back); 295 296 splx(s); 297 } 298 299 unregister_hb_intr2(func) 300 int (*func)(); 301 { 302 register struct hb_intr *p, *q; 303 register int s = splclock(); 304 305 for (p = hb_intr2.forw; p != &hb_intr2; p = p->forw) { 306 if (p->func == func) { 307 remque(p); 308 free((caddr_t)p, M_DEVBUF); 309 break; 310 } 311 } 312 313 splx(s); 314 } 315 316 register_hb_intr4(func, arg, pri) 317 int (*func)(); 318 int arg; 319 int pri; 320 { 321 register struct hb_intr *p, *q; 322 register int s = splclock(); 323 324 p = malloc(sizeof (struct hb_intr), M_DEVBUF, M_WAITOK); 325 p->pri = pri; 326 p->func = func; 327 p->arg = arg; 328 329 for (q = hb_intr4.forw; q != &hb_intr4; q = q->forw) 330 if (p->pri < q->pri) 331 break; 332 insque(p, q->back); 333 334 splx(s); 335 } 336 337 unregister_hb_intr4(func) 338 int (*func)(); 339 { 340 register struct hb_intr *p, *q; 341 register int s = splclock(); 342 343 for (p = hb_intr4.forw; p != &hb_intr4; p = p->forw) { 344 if (p->func == func) { 345 remque(p); 346 free((caddr_t)p, M_DEVBUF); 347 break; 348 } 349 } 350 351 splx(s); 352 } 353 354 extern struct vmmeter cnt; 355 356 exec_hb_intr2() 357 { 358 register struct hb_intr *p; 359 360 for (p = hb_intr2.forw; p != &hb_intr2; p = p->forw) { 361 if ((int)p->func == 0) 362 goto out; 363 364 if ((*(p->func))(p->arg)) { 365 cnt.v_intr++; /* statistics info. */ 366 return; 367 } 368 } 369 out: 370 #ifdef news3400 371 return; 372 #else 373 printf("stray hb intr 2\n"); 374 #endif 375 } 376 377 exec_hb_intr4() 378 { 379 register struct hb_intr *p; 380 381 for (p = hb_intr4.forw; p != &hb_intr4; p = p->forw) { 382 if ((int)p->func == 0) 383 goto out; 384 385 if ((*(p->func))(p->arg)) { 386 cnt.v_intr++; /* statistics info. */ 387 return; 388 } 389 } 390 out: 391 #ifdef news3400 392 return; 393 #else 394 printf("stray hb intr 4\n"); 395 #endif 396 } 397 /*kos111*/ 398 #endif /* CPU_SINGLE */ 399