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