1/* $NetBSD: sc_wrap.c,v 1.34 2023/12/20 15:29:05 thorpej Exp $ */ 2 3/* 4 * This driver is slow! Need to rewrite. 5 */ 6 7#include <sys/cdefs.h> 8__KERNEL_RCSID(0, "$NetBSD: sc_wrap.c,v 1.34 2023/12/20 15:29:05 thorpej Exp $"); 9 10#include <sys/types.h> 11#include <sys/param.h> 12#include <sys/systm.h> 13#include <sys/kernel.h> 14#include <sys/device.h> 15#include <sys/proc.h> 16#include <sys/buf.h> 17 18#include <uvm/uvm_extern.h> 19 20#include <dev/scsipi/scsi_all.h> 21#include <dev/scsipi/scsipi_all.h> 22#include <dev/scsipi/scsiconf.h> 23#include <dev/scsipi/scsi_message.h> 24 25#include <newsmips/dev/hbvar.h> 26#include <newsmips/dev/scsireg.h> 27#include <newsmips/dev/dmac_0448.h> 28#include <newsmips/dev/screg_1185.h> 29 30#include <machine/adrsmap.h> 31#include <machine/autoconf.h> 32#include <machine/machConst.h> 33 34#include <mips/cache.h> 35 36static int cxd1185_match(device_t, cfdata_t, void *); 37static void cxd1185_attach(device_t, device_t, void *); 38 39CFATTACH_DECL_NEW(sc, sizeof(struct sc_softc), 40 cxd1185_match, cxd1185_attach, NULL, NULL); 41 42void cxd1185_init(struct sc_softc *); 43static void free_scb(struct sc_softc *, struct sc_scb *); 44static struct sc_scb *get_scb(struct sc_softc *, int); 45static void sc_scsipi_request(struct scsipi_channel *, 46 scsipi_adapter_req_t, void *); 47static int sc_poll(struct sc_softc *, int, int); 48static void sc_sched(struct sc_softc *); 49void sc_done(struct sc_scb *); 50int sc_intr(void *); 51static void cxd1185_timeout(void *); 52 53extern void sc_send(struct sc_scb *, int, int); 54extern int scintr(void); 55extern void scsi_hardreset(void); 56extern int sc_busy(struct sc_softc *, int); 57extern paddr_t kvtophys(vaddr_t); 58 59static int sc_disconnect = IDT_DISCON; 60 61int 62cxd1185_match(device_t parent, cfdata_t cf, void *aux) 63{ 64 struct hb_attach_args *ha = aux; 65 66 if (strcmp(ha->ha_name, "sc")) 67 return 0; 68 69 return 1; 70} 71 72void 73cxd1185_attach(device_t parent, device_t self, void *aux) 74{ 75 struct sc_softc *sc = device_private(self); 76 struct hb_attach_args *ha = aux; 77 struct sc_scb *scb; 78 int i, intlevel; 79 80 sc->sc_dev = self; 81 82 intlevel = ha->ha_level; 83 if (intlevel == -1) { 84#if 0 85 aprint_error(": interrupt level not configured\n"); 86 return; 87#else 88 aprint_normal(": interrupt level not configured; using"); 89 intlevel = 0; 90#endif 91 } 92 aprint_normal(" level %d\n", intlevel); 93 94 if (sc_idenr & 0x08) 95 sc->scsi_1185AQ = 1; 96 else 97 sc->scsi_1185AQ = 0; 98 99 sc->sc_adapter.adapt_dev = self; 100 sc->sc_adapter.adapt_nchannels = 1; 101 sc->sc_adapter.adapt_openings = 7; 102 sc->sc_adapter.adapt_max_periph = 1; 103 sc->sc_adapter.adapt_ioctl = NULL; 104 sc->sc_adapter.adapt_minphys = minphys; 105 sc->sc_adapter.adapt_request = sc_scsipi_request; 106 107 memset(&sc->sc_channel, 0, sizeof(sc->sc_channel)); 108 sc->sc_channel.chan_adapter = &sc->sc_adapter; 109 sc->sc_channel.chan_bustype = &scsi_bustype; 110 sc->sc_channel.chan_channel = 0; 111 sc->sc_channel.chan_ntargets = 8; 112 sc->sc_channel.chan_nluns = 8; 113 sc->sc_channel.chan_id = 7; 114 115 TAILQ_INIT(&sc->ready_list); 116 TAILQ_INIT(&sc->free_list); 117 118 scb = sc->sc_scb; 119 for (i = 0; i < 24; i++) { /* XXX 24 */ 120 TAILQ_INSERT_TAIL(&sc->free_list, scb, chain); 121 scb++; 122 } 123 124 cxd1185_init(sc); 125 DELAY(100000); 126 127 hb_intr_establish(intlevel, INTEN1_DMA, IPL_BIO, sc_intr, sc); 128 129 config_found(self, &sc->sc_channel, scsiprint, CFARGS_NONE); 130} 131 132void 133cxd1185_init(struct sc_softc *sc) 134{ 135 int i; 136 137 for (i = 0; i < 8; i++) 138 sc->inuse[i] = 0; 139 140 scsi_hardreset(); 141} 142 143void 144free_scb(struct sc_softc *sc, struct sc_scb *scb) 145{ 146 int s; 147 148 s = splbio(); 149 150 TAILQ_INSERT_HEAD(&sc->free_list, scb, chain); 151 152 /* 153 * If there were none, wake anybody waiting for one to come free, 154 * starting with queued entries. 155 */ 156 if (scb->chain.tqe_next == 0) 157 wakeup(&sc->free_list); 158 159 splx(s); 160} 161 162struct sc_scb * 163get_scb(struct sc_softc *sc, int flags) 164{ 165 int s; 166 struct sc_scb *scb; 167 168 s = splbio(); 169 170 while ((scb = sc->free_list.tqh_first) == NULL && 171 (flags & XS_CTL_NOSLEEP) == 0) 172 tsleep(&sc->free_list, PRIBIO, "sc_scb", 0); 173 if (scb) { 174 TAILQ_REMOVE(&sc->free_list, scb, chain); 175 } 176 177 splx(s); 178 return scb; 179} 180 181void 182sc_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, 183 void *arg) 184{ 185 struct scsipi_xfer *xs; 186 struct scsipi_periph *periph; 187 struct sc_softc *sc = device_private(chan->chan_adapter->adapt_dev); 188 struct sc_scb *scb; 189 int flags, s; 190 int target; 191 192 switch (req) { 193 case ADAPTER_REQ_RUN_XFER: 194 xs = arg; 195 periph = xs->xs_periph; 196 197 flags = xs->xs_control; 198 if ((scb = get_scb(sc, flags)) == NULL) 199 panic("%s: no scb", __func__); 200 201 scb->xs = xs; 202 scb->flags = 0; 203 scb->sc_ctag = 0; 204 scb->sc_coffset = 0; 205 scb->istatus = 0; 206 scb->tstatus = 0; 207 scb->message = 0; 208 memset(scb->msgbuf, 0, sizeof(scb->msgbuf)); 209 210 s = splbio(); 211 212 TAILQ_INSERT_TAIL(&sc->ready_list, scb, chain); 213 sc_sched(sc); 214 splx(s); 215 216 if (flags & XS_CTL_POLL) { 217 target = periph->periph_target; 218 if (sc_poll(sc, target, xs->timeout)) { 219 printf("sc: timeout (retry)\n"); 220 if (sc_poll(sc, target, xs->timeout)) { 221 printf("sc: timeout\n"); 222 } 223 } 224 /* called during autoconfig only... */ 225 mips_dcache_wbinv_all(); /* Flush DCache */ 226 } 227 return; 228 case ADAPTER_REQ_GROW_RESOURCES: 229 /* XXX Not supported. */ 230 return; 231 case ADAPTER_REQ_SET_XFER_MODE: 232 /* XXX Not supported. */ 233 return; 234 } 235} 236 237/* 238 * Used when interrupt driven I/O isn't allowed, e.g. during boot. 239 */ 240int 241sc_poll(struct sc_softc *sc, int chan, int count) 242{ 243 volatile uint8_t *int_stat = (void *)INTST1; 244 volatile uint8_t *int_clear = (void *)INTCLR1; 245 246 while (sc_busy(sc, chan)) { 247 if (*int_stat & INTST1_DMA) { 248 *int_clear = INTST1_DMA; 249 if (dmac_gstat & CH_INT(CH_SCSI)) { 250 if (dmac_gstat & CH_MRQ(CH_SCSI)) { 251 DELAY(50); 252 if (dmac_gstat & CH_MRQ(CH_SCSI)) 253 printf("dma_poll\n"); 254 } 255 DELAY(10); 256 scintr(); 257 } 258 } 259 DELAY(1000); 260 count--; 261 if (count <= 0) 262 return 1; 263 } 264 return 0; 265} 266 267void 268sc_sched(struct sc_softc *sc) 269{ 270 struct scsipi_xfer *xs; 271 struct scsipi_periph *periph; 272 int ie = 0; 273 int flags; 274 int chan, lun; 275 struct sc_scb *scb, *nextscb; 276 277 scb = sc->ready_list.tqh_first; 278start: 279 if (scb == NULL) 280 return; 281 282 xs = scb->xs; 283 periph = xs->xs_periph; 284 chan = periph->periph_target; 285 flags = xs->xs_control; 286 287 if (sc->inuse[chan]) { 288 scb = scb->chain.tqe_next; 289 goto start; 290 } 291 sc->inuse[chan] = 1; 292 293 if (flags & XS_CTL_RESET) 294 printf("SCSI RESET\n"); 295 296 lun = periph->periph_lun; 297 298 scb->identify = MSG_IDENT | sc_disconnect | (lun & IDT_DRMASK); 299 scb->sc_ctrnscnt = xs->datalen; 300 301 /* make va->pa mapping table for DMA */ 302 if (xs->datalen > 0) { 303 uint32_t pn, pages, offset; 304 int i; 305 vaddr_t va; 306 307#if 0 308 memset(&sc->sc_map[chan], 0, sizeof(struct sc_map)); 309#endif 310 311 va = (vaddr_t)xs->data; 312 313 offset = va & PGOFSET; 314 pages = (offset + xs->datalen + PAGE_SIZE -1 ) >> PGSHIFT; 315 if (pages >= NSCMAP) 316 panic("sc_map: Too many pages"); 317 318 for (i = 0; i < pages; i++) { 319 pn = kvtophys(va) >> PGSHIFT; 320 sc->sc_map[chan].mp_addr[i] = pn; 321 va += PAGE_SIZE; 322 } 323 324 sc->sc_map[chan].mp_offset = offset; 325 sc->sc_map[chan].mp_pages = pages; 326 scb->sc_map = &sc->sc_map[chan]; 327 } 328 329 if ((flags & XS_CTL_POLL) == 0) 330 ie = SCSI_INTEN; 331 332 if (xs->data) 333 scb->sc_cpoint = (void *)xs->data; 334 else 335 scb->sc_cpoint = scb->msgbuf; 336 scb->scb_softc = sc; 337 338 callout_reset(&scb->xs->xs_callout, hz * 10, cxd1185_timeout, scb); 339 sc_send(scb, chan, ie); 340 callout_stop(&scb->xs->xs_callout); 341 342 nextscb = scb->chain.tqe_next; 343 344 TAILQ_REMOVE(&sc->ready_list, scb, chain); 345 346 scb = nextscb; 347 348 goto start; 349} 350 351void 352sc_done(struct sc_scb *scb) 353{ 354 struct scsipi_xfer *xs = scb->xs; 355 struct scsipi_periph *periph = xs->xs_periph; 356 struct sc_softc *sc; 357 358 sc = device_private(periph->periph_channel->chan_adapter->adapt_dev); 359 xs->resid = 0; 360 xs->status = 0; 361 362 if (scb->istatus != INST_EP) { 363 if (scb->istatus == (INST_EP|INST_TO)) 364 xs->error = XS_SELTIMEOUT; 365 else { 366 printf("SC(i): [istatus=0x%x, tstatus=0x%x]\n", 367 scb->istatus, scb->tstatus); 368 xs->error = XS_DRIVER_STUFFUP; 369 } 370 } 371 372 switch (scb->tstatus) { 373 374 case TGST_GOOD: 375 break; 376 377 case TGST_CC: 378 xs->status = SCSI_CHECK; 379 if (xs->error == 0) 380 xs->error = XS_BUSY; 381 break; 382 383 default: 384 printf("SC(t): [istatus=0x%x, tstatus=0x%x]\n", 385 scb->istatus, scb->tstatus); 386 break; 387 } 388 389 scsipi_done(xs); 390 free_scb(sc, scb); 391 sc->inuse[periph->periph_target] = 0; 392 sc_sched(sc); 393} 394 395int 396sc_intr(void *v) 397{ 398 /* struct sc_softc *sc = v; */ 399 volatile uint8_t *gsp = (uint8_t *)DMAC_GSTAT; 400 u_int gstat = *gsp; 401 int mrqb, i; 402 403 if ((gstat & CH_INT(CH_SCSI)) == 0) 404 return 0; 405 406 /* 407 * when DMA interrupt occurs there remain some untransferred data. 408 * wait data transfer completion. 409 */ 410 mrqb = (gstat & CH_INT(CH_SCSI)) << 1; 411 if (gstat & mrqb) { 412 /* 413 * XXX SHOULD USE DELAY() 414 */ 415 for (i = 0; i < 50; i++) 416 ; 417 if (*gsp & mrqb) 418 printf("%s: MRQ\n", __func__); 419 } 420 scintr(); 421 422 return 1; 423} 424 425 426#if 0 427/* 428 * SCOP_RSENSE request 429 */ 430void 431scop_rsense(int intr, struct scsi *sc_param, int lun, int ie, int count, 432 void *param) 433{ 434 435 memset(sc_param, 0, sizeof(struct scsi)); 436 sc_param->identify = MSG_IDENT | sc_disconnect | (lun & IDT_DRMASK); 437 sc_param->sc_lun = lun; 438 439 sc_param->sc_cpoint = (uint8_t *)param; 440 sc_param->sc_ctrnscnt = count; 441 442 /* sc_cdb */ 443 sc_param->sc_opcode = SCOP_RSENSE; 444 sc_param->sc_count = count; 445 446 sc_go(intr, sc_param, ie, sc_param); 447} 448#endif 449 450void 451cxd1185_timeout(void *arg) 452{ 453 struct sc_scb *scb = arg; 454 struct scsipi_xfer *xs = scb->xs; 455 struct scsipi_periph *periph = xs->xs_periph; 456 int chan; 457 458 chan = periph->periph_target; 459 460 printf("sc: timeout ch=%d\n", chan); 461 462 /* XXX abort transfer and ... */ 463} 464