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