Annotation of sys/dev/ic/iha.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: iha.c,v 1.26 2007/04/10 17:47:55 miod Exp $ */
2: /*-------------------------------------------------------------------------
3: *
4: * Device driver for the INI-9XXXU/UW or INIC-940/950 PCI SCSI Controller.
5: *
6: * Written for 386bsd and FreeBSD by
7: * Winston Hung <winstonh@initio.com>
8: *
9: * Copyright (c) 1997-1999 Initio Corp
10: * Copyright (c) 2000-2002 Ken Westerback
11: *
12: * Redistribution and use in source and binary forms, with or without
13: * modification, are permitted provided that the following conditions
14: * are met:
15: * 1. Redistributions of source code must retain the above copyright
16: * notice, this list of conditions and the following disclaimer,
17: * without modification, immediately at the beginning of the file.
18: * 2. The name of the author may not be used to endorse or promote products
19: * derived from this software without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24: * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
25: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27: * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30: * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31: * THE POSSIBILITY OF SUCH DAMAGE.
32: *
33: *-------------------------------------------------------------------------
34: */
35: #include <sys/param.h>
36: #include <sys/systm.h>
37: #include <sys/kernel.h>
38: #include <sys/buf.h>
39: #include <sys/device.h>
40:
41: #include <machine/bus.h>
42: #include <machine/intr.h>
43:
44: #include <scsi/scsi_all.h>
45: #include <scsi/scsiconf.h>
46: #include <scsi/scsi_message.h>
47:
48: #include <dev/ic/iha.h>
49:
50: /* #define IHA_DEBUG_STATE */
51:
52: struct cfdriver iha_cd = {
53: NULL, "iha", DV_DULL
54: };
55:
56: struct scsi_adapter iha_switch = {
57: iha_scsi_cmd, /* int (*scsi_cmd)(struct scsi_xfer *); */
58: iha_minphys, /* void (*scsi_minphys)(struct buf *); */
59: NULL, /* int (*open_target_lu)(void); */
60: NULL /* int (*close_target_lu)(void); */
61: };
62:
63: struct scsi_device iha_dev = {
64: NULL, /* Use default error handler */
65: NULL, /* have a queue, served by this */
66: NULL, /* have no async handler */
67: NULL, /* Use default 'done' routine */
68: };
69:
70: /*
71: * SCSI Rate Table, indexed by FLAG_SCSI_RATE field of
72: * TCS_Flags.
73: */
74: static const u_int8_t iha_rate_tbl[] = {
75: /* fast 20 */
76: /* nanosecond divide by 4 */
77: 12, /* 50ns, 20M */
78: 18, /* 75ns, 13.3M */
79: 25, /* 100ns, 10M */
80: 31, /* 125ns, 8M */
81: 37, /* 150ns, 6.6M */
82: 43, /* 175ns, 5.7M */
83: 50, /* 200ns, 5M */
84: 62 /* 250ns, 4M */
85: };
86:
87: int iha_setup_sg_list(struct iha_softc *, struct iha_scb *);
88: u_int8_t iha_data_over_run(struct iha_scb *);
89: int iha_push_sense_request(struct iha_softc *, struct iha_scb *);
90: void iha_timeout(void *);
91: int iha_alloc_scbs(struct iha_softc *);
92: void iha_read_eeprom(bus_space_tag_t, bus_space_handle_t,
93: struct iha_nvram *);
94: void iha_se2_instr(bus_space_tag_t, bus_space_handle_t, u_int8_t);
95: u_int16_t iha_se2_rd(bus_space_tag_t, bus_space_handle_t, u_int8_t);
96: void iha_reset_scsi_bus(struct iha_softc *);
97: void iha_reset_chip(struct iha_softc *,
98: bus_space_tag_t, bus_space_handle_t);
99: void iha_reset_dma(bus_space_tag_t, bus_space_handle_t);
100: void iha_reset_tcs(struct tcs *, u_int8_t);
101: void iha_print_info(struct iha_softc *, int);
102: void iha_done_scb(struct iha_softc *, struct iha_scb *);
103: void iha_exec_scb(struct iha_softc *, struct iha_scb *);
104: void iha_main(struct iha_softc *, bus_space_tag_t, bus_space_handle_t);
105: void iha_scsi(struct iha_softc *, bus_space_tag_t, bus_space_handle_t);
106: int iha_wait(struct iha_softc *, bus_space_tag_t, bus_space_handle_t,
107: u_int8_t);
108: void iha_mark_busy_scb(struct iha_scb *);
109: void iha_append_free_scb(struct iha_softc *, struct iha_scb *);
110: struct iha_scb *iha_pop_free_scb(struct iha_softc *);
111: void iha_append_done_scb(struct iha_softc *, struct iha_scb *,
112: u_int8_t);
113: struct iha_scb *iha_pop_done_scb(struct iha_softc *);
114: void iha_append_pend_scb(struct iha_softc *, struct iha_scb *);
115: void iha_push_pend_scb(struct iha_softc *, struct iha_scb *);
116: struct iha_scb *iha_find_pend_scb(struct iha_softc *);
117: void iha_sync_done(struct iha_softc *,
118: bus_space_tag_t, bus_space_handle_t);
119: void iha_wide_done(struct iha_softc *,
120: bus_space_tag_t, bus_space_handle_t);
121: void iha_bad_seq(struct iha_softc *);
122: int iha_next_state(struct iha_softc *,
123: bus_space_tag_t, bus_space_handle_t);
124: int iha_state_1(struct iha_softc *,
125: bus_space_tag_t, bus_space_handle_t);
126: int iha_state_2(struct iha_softc *,
127: bus_space_tag_t, bus_space_handle_t);
128: int iha_state_3(struct iha_softc *,
129: bus_space_tag_t, bus_space_handle_t);
130: int iha_state_4(struct iha_softc *,
131: bus_space_tag_t, bus_space_handle_t);
132: int iha_state_5(struct iha_softc *,
133: bus_space_tag_t, bus_space_handle_t);
134: int iha_state_6(struct iha_softc *,
135: bus_space_tag_t, bus_space_handle_t);
136: int iha_state_8(struct iha_softc *,
137: bus_space_tag_t, bus_space_handle_t);
138: void iha_set_ssig(bus_space_tag_t,
139: bus_space_handle_t, u_int8_t, u_int8_t);
140: int iha_xpad_in(struct iha_softc *,
141: bus_space_tag_t, bus_space_handle_t);
142: int iha_xpad_out(struct iha_softc *,
143: bus_space_tag_t, bus_space_handle_t);
144: int iha_xfer_data(struct iha_scb *,
145: bus_space_tag_t, bus_space_handle_t,
146: int direction);
147: int iha_status_msg(struct iha_softc *,
148: bus_space_tag_t, bus_space_handle_t);
149: int iha_msgin(struct iha_softc *, bus_space_tag_t, bus_space_handle_t);
150: int iha_msgin_sdtr(struct iha_softc *);
151: int iha_msgin_extended(struct iha_softc *,
152: bus_space_tag_t, bus_space_handle_t);
153: int iha_msgin_ignore_wid_resid(struct iha_softc *,
154: bus_space_tag_t, bus_space_handle_t);
155: int iha_msgout(struct iha_softc *,
156: bus_space_tag_t, bus_space_handle_t, u_int8_t);
157: int iha_msgout_extended(struct iha_softc *,
158: bus_space_tag_t, bus_space_handle_t);
159: void iha_msgout_abort(struct iha_softc *,
160: bus_space_tag_t, bus_space_handle_t, u_int8_t);
161: int iha_msgout_reject(struct iha_softc *,
162: bus_space_tag_t, bus_space_handle_t);
163: int iha_msgout_sdtr(struct iha_softc *,
164: bus_space_tag_t, bus_space_handle_t);
165: int iha_msgout_wdtr(struct iha_softc *,
166: bus_space_tag_t, bus_space_handle_t);
167: void iha_select(struct iha_softc *,
168: bus_space_tag_t, bus_space_handle_t,
169: struct iha_scb *, u_int8_t);
170: void iha_busfree(struct iha_softc *,
171: bus_space_tag_t, bus_space_handle_t);
172: int iha_resel(struct iha_softc *, bus_space_tag_t, bus_space_handle_t);
173: void iha_abort_xs(struct iha_softc *, struct scsi_xfer *, u_int8_t);
174:
175: /*
176: * iha_intr - the interrupt service routine for the iha driver
177: */
178: int
179: iha_intr(arg)
180: void *arg;
181: {
182: bus_space_handle_t ioh;
183: struct iha_softc *sc;
184: bus_space_tag_t iot;
185: int s;
186:
187: sc = (struct iha_softc *)arg;
188: iot = sc->sc_iot;
189: ioh = sc->sc_ioh;
190:
191: if ((bus_space_read_1(iot, ioh, TUL_STAT0) & INTPD) == 0)
192: return (0);
193:
194: s = splbio(); /* XXX - Or are interrupts off when ISR's are called? */
195:
196: if (sc->HCS_Semaph != SEMAPH_IN_MAIN) {
197: /* XXX - need these inside a splbio()/splx()? */
198: bus_space_write_1(iot, ioh, TUL_IMSK, MASK_ALL);
199: sc->HCS_Semaph = SEMAPH_IN_MAIN;
200:
201: iha_main(sc, iot, ioh);
202:
203: sc->HCS_Semaph = ~SEMAPH_IN_MAIN;
204: bus_space_write_1(iot, ioh, TUL_IMSK, (MASK_ALL & ~MSCMP));
205: }
206:
207: splx(s);
208:
209: return (1);
210: }
211:
212: /*
213: * iha_setup_sg_list - initialize scatter gather list of pScb from
214: * pScb->SCB_DataDma.
215: */
216: int
217: iha_setup_sg_list(sc, pScb)
218: struct iha_softc *sc;
219: struct iha_scb *pScb;
220: {
221: bus_dma_segment_t *segs = pScb->SCB_DataDma->dm_segs;
222: int i, error, nseg = pScb->SCB_DataDma->dm_nsegs;
223:
224: if (nseg > 1) {
225: error = bus_dmamap_load(sc->sc_dmat, pScb->SCB_SGDma,
226: pScb->SCB_SGList, sizeof(pScb->SCB_SGList), NULL,
227: (pScb->SCB_Flags & SCSI_NOSLEEP) ?
228: BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
229: if (error) {
230: sc_print_addr(pScb->SCB_Xs->sc_link);
231: printf("error %d loading SG list dma map\n", error);
232: return (error);
233: }
234:
235: /*
236: * Only set FLAG_SG when SCB_SGDma is loaded so iha_scsi_done
237: * will not unload an unloaded map.
238: */
239: pScb->SCB_Flags |= FLAG_SG;
240: bzero(pScb->SCB_SGList, sizeof(pScb->SCB_SGList));
241:
242: pScb->SCB_SGIdx = 0;
243: pScb->SCB_SGCount = nseg;
244:
245: for (i=0; i < nseg; i++) {
246: pScb->SCB_SGList[i].SG_Len = segs[i].ds_len;
247: pScb->SCB_SGList[i].SG_Addr = segs[i].ds_addr;
248: }
249:
250: bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma,
251: 0, sizeof(pScb->SCB_SGList), BUS_DMASYNC_PREWRITE);
252: }
253:
254: return (0);
255: }
256:
257: /*
258: * iha_scsi_cmd - start execution of a SCSI command. This is called
259: * from the generic SCSI driver via the field
260: * sc_adapter.scsi_cmd of iha_softc.
261: */
262: int
263: iha_scsi_cmd(xs)
264: struct scsi_xfer *xs;
265: {
266: struct iha_scb *pScb;
267: struct scsi_link *sc_link = xs->sc_link;
268: struct iha_softc *sc = sc_link->adapter_softc;
269: int error;
270:
271: if ((xs->cmdlen > 12) || (sc_link->target >= IHA_MAX_TARGETS)) {
272: xs->error = XS_DRIVER_STUFFUP;
273: return (COMPLETE);
274: }
275:
276: pScb = iha_pop_free_scb(sc);
277: if (pScb == NULL) {
278: /* XXX - different xs->error/return if
279: * SCSI_POLL/_NOSLEEP? */
280: return (TRY_AGAIN_LATER);
281: }
282:
283: pScb->SCB_Target = sc_link->target;
284: pScb->SCB_Lun = sc_link->lun;
285: pScb->SCB_Tcs = &sc->HCS_Tcs[pScb->SCB_Target];
286: pScb->SCB_Flags = xs->flags;
287: pScb->SCB_Ident = MSG_IDENTIFYFLAG |
288: (pScb->SCB_Lun & MSG_IDENTIFY_LUNMASK);
289:
290: if ((xs->cmd->opcode != REQUEST_SENSE)
291: && ((pScb->SCB_Flags & SCSI_POLL) == 0))
292: pScb->SCB_Ident |= MSG_IDENTIFY_DISCFLAG;
293:
294: pScb->SCB_Xs = xs;
295: pScb->SCB_CDBLen = xs->cmdlen;
296: bcopy(xs->cmd, &pScb->SCB_CDB, xs->cmdlen);
297:
298: pScb->SCB_BufCharsLeft = pScb->SCB_BufChars = xs->datalen;
299:
300: if ((pScb->SCB_Flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) != 0) {
301: #ifdef TFS
302: if (pScb->SCB_Flags & SCSI_DATA_UIO)
303: error = bus_dmamap_load_uio(sc->sc_dmat,
304: pScb->SCB_DataDma, (struct uio *)xs->data,
305: (pScb->SCB_Flags & SCSI_NOSLEEP) ?
306: BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
307: else
308: #endif /* TFS */
309: error = bus_dmamap_load(sc->sc_dmat, pScb->SCB_DataDma,
310: xs->data, pScb->SCB_BufChars, NULL,
311: (pScb->SCB_Flags & SCSI_NOSLEEP) ?
312: BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
313:
314: if (error) {
315: sc_print_addr(xs->sc_link);
316: if (error == EFBIG)
317: printf("buffer needs >%d dma segments\n",
318: IHA_MAX_SG_ENTRIES);
319: else
320: printf("error %d loading buffer dma map\n",
321: error);
322:
323: iha_append_free_scb(sc, pScb);
324:
325: xs->error = XS_DRIVER_STUFFUP;
326: return (COMPLETE);
327: }
328: bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma,
329: 0, pScb->SCB_BufChars,
330: (pScb->SCB_Flags & SCSI_DATA_IN) ?
331: BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
332:
333: error = iha_setup_sg_list(sc, pScb);
334: if (error) {
335: bus_dmamap_unload(sc->sc_dmat, pScb->SCB_DataDma);
336: xs->error = XS_DRIVER_STUFFUP;
337: return (COMPLETE);
338: }
339:
340: }
341:
342: /*
343: * Always initialize the stimeout structure as it may
344: * contain garbage that confuses timeout_del() later on.
345: * But, timeout_add() ONLY if we are not polling.
346: */
347: timeout_set(&xs->stimeout, iha_timeout, pScb);
348: if ((pScb->SCB_Flags & SCSI_POLL) == 0)
349: timeout_add(&xs->stimeout, (xs->timeout/1000) * hz);
350:
351: iha_exec_scb(sc, pScb);
352:
353: if ((xs->flags & ITSDONE) == 0)
354: return (SUCCESSFULLY_QUEUED);
355: else
356: return (COMPLETE);
357: }
358:
359: /*
360: * iha_init_tulip - initialize the inic-940/950 card and the rest of the
361: * iha_softc structure supplied
362: */
363: int
364: iha_init_tulip(sc)
365: struct iha_softc *sc;
366: {
367: struct iha_scb *pScb;
368: struct iha_nvram_scsi *pScsi;
369: bus_space_handle_t ioh;
370: struct iha_nvram iha_nvram;
371: bus_space_tag_t iot;
372: int i, error;
373:
374: iot = sc->sc_iot;
375: ioh = sc->sc_ioh;
376:
377: iha_read_eeprom(iot, ioh, &iha_nvram);
378:
379: pScsi = &iha_nvram.NVM_Scsi[0];
380:
381: /*
382: * fill in the prototype scsi_link.
383: */
384: sc->sc_link.adapter_softc = sc;
385: sc->sc_link.adapter = &iha_switch;
386: sc->sc_link.device = &iha_dev;
387: sc->sc_link.openings = 4; /* # xs's allowed per device */
388: sc->sc_link.adapter_target = pScsi->NVM_SCSI_Id;
389: sc->sc_link.adapter_buswidth = pScsi->NVM_SCSI_Targets;
390:
391: /*
392: * fill in the rest of the iha_softc fields
393: */
394: sc->HCS_Semaph = ~SEMAPH_IN_MAIN;
395: sc->HCS_JSStatus0 = 0;
396: sc->HCS_ActScb = NULL;
397:
398: TAILQ_INIT(&sc->HCS_FreeScb);
399: TAILQ_INIT(&sc->HCS_PendScb);
400: TAILQ_INIT(&sc->HCS_DoneScb);
401:
402: error = iha_alloc_scbs(sc);
403: if (error != 0)
404: return (error);
405:
406: for (i = 0, pScb = sc->HCS_Scb; i < IHA_MAX_SCB; i++, pScb++) {
407: pScb->SCB_TagId = i;
408:
409: error = bus_dmamap_create(sc->sc_dmat,
410: (IHA_MAX_SG_ENTRIES-1) * PAGE_SIZE, IHA_MAX_SG_ENTRIES,
411: (IHA_MAX_SG_ENTRIES-1) * PAGE_SIZE, 0,
412: BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &pScb->SCB_DataDma);
413:
414: if (error != 0) {
415: printf("%s: couldn't create SCB data DMA map, error = %d\n",
416: sc->sc_dev.dv_xname, error);
417: return (error);
418: }
419:
420: error = bus_dmamap_create(sc->sc_dmat,
421: sizeof(pScb->SCB_SGList), 1,
422: sizeof(pScb->SCB_SGList), 0,
423: BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
424: &pScb->SCB_SGDma);
425: if (error != 0) {
426: printf("%s: couldn't create SCB SG DMA map, error = %d\n",
427: sc->sc_dev.dv_xname, error);
428: return (error);
429: }
430:
431: TAILQ_INSERT_TAIL(&sc->HCS_FreeScb, pScb, SCB_ScbList);
432: }
433:
434: /* Mask all the interrupts */
435: bus_space_write_1(iot, ioh, TUL_IMSK, MASK_ALL);
436:
437: /* Stop any I/O and reset the scsi module */
438: iha_reset_dma(iot, ioh);
439: bus_space_write_1(iot, ioh, TUL_SCTRL0, RSMOD);
440:
441: /* Program HBA's SCSI ID */
442: bus_space_write_1(iot, ioh, TUL_SID, sc->sc_link.adapter_target << 4);
443:
444: /*
445: * Configure the channel as requested by the NVRAM settings read
446: * into iha_nvram by iha_read_eeprom() above.
447: */
448:
449: if ((pScsi->NVM_SCSI_Cfg & CFG_EN_PAR) != 0)
450: sc->HCS_SConf1 = (SCONFIG0DEFAULT | SPCHK);
451: else
452: sc->HCS_SConf1 = (SCONFIG0DEFAULT);
453: bus_space_write_1(iot, ioh, TUL_SCONFIG0, sc->HCS_SConf1);
454:
455: /* selection time out in units of 1.6385 millisecond = 250 ms */
456: bus_space_write_1(iot, ioh, TUL_STIMO, 153);
457:
458: /* Enable desired SCSI termination configuration read from eeprom */
459: bus_space_write_1(iot, ioh, TUL_DCTRL0,
460: (pScsi->NVM_SCSI_Cfg & (CFG_ACT_TERM1 | CFG_ACT_TERM2)));
461:
462: bus_space_write_1(iot, ioh, TUL_GCTRL1,
463: ((pScsi->NVM_SCSI_Cfg & CFG_AUTO_TERM) >> 4)
464: | (bus_space_read_1(iot, ioh, TUL_GCTRL1) & (~ATDEN)));
465:
466: for (i = 0; i < IHA_MAX_TARGETS; i++) {
467: sc->HCS_Tcs[i].TCS_Flags = pScsi->NVM_SCSI_TargetFlags[i];
468: iha_reset_tcs(&sc->HCS_Tcs[i], sc->HCS_SConf1);
469: }
470:
471: iha_reset_chip(sc, iot, ioh);
472: bus_space_write_1(iot, ioh, TUL_SIEN, ALL_INTERRUPTS);
473:
474: return (0);
475: }
476:
477: /*
478: * iha_minphys - reduce bp->b_bcount to something less than
479: * or equal to the largest I/O possible through
480: * the adapter. Called from higher layers
481: * via sc->sc_adapter.scsi_minphys.
482: */
483: void
484: iha_minphys(bp)
485: struct buf *bp;
486: {
487: if (bp->b_bcount > ((IHA_MAX_SG_ENTRIES - 1) * PAGE_SIZE))
488: bp->b_bcount = ((IHA_MAX_SG_ENTRIES - 1) * PAGE_SIZE);
489:
490: minphys(bp);
491: }
492:
493: /*
494: * iha_reset_dma - abort any active DMA xfer, reset tulip FIFO.
495: */
496: void
497: iha_reset_dma(iot, ioh)
498: bus_space_tag_t iot;
499: bus_space_handle_t ioh;
500: {
501: if ((bus_space_read_1(iot, ioh, TUL_ISTUS1) & XPEND) != 0) {
502: /* if DMA xfer is pending, abort DMA xfer */
503: bus_space_write_1(iot, ioh, TUL_DCMD, ABTXFR);
504: /* wait Abort DMA xfer done */
505: while ((bus_space_read_1(iot, ioh, TUL_ISTUS0) & DABT) == 0)
506: ;
507: }
508:
509: bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
510: }
511:
512: /*
513: * iha_pop_free_scb - return the first free SCB, or NULL if there are none.
514: */
515: struct iha_scb *
516: iha_pop_free_scb(sc)
517: struct iha_softc *sc;
518: {
519: struct iha_scb *pScb;
520: int s;
521:
522: s = splbio();
523:
524: pScb = TAILQ_FIRST(&sc->HCS_FreeScb);
525:
526: if (pScb != NULL) {
527: pScb->SCB_Status = STATUS_RENT;
528: TAILQ_REMOVE(&sc->HCS_FreeScb, pScb, SCB_ScbList);
529: }
530:
531: splx(s);
532:
533: return (pScb);
534: }
535:
536: /*
537: * iha_append_free_scb - append the supplied SCB to the tail of the
538: * HCS_FreeScb queue after clearing and resetting
539: * everything possible.
540: */
541: void
542: iha_append_free_scb(sc, pScb)
543: struct iha_softc *sc;
544: struct iha_scb *pScb;
545: {
546: int s;
547:
548: s = splbio();
549:
550: if (pScb == sc->HCS_ActScb)
551: sc->HCS_ActScb = NULL;
552:
553: pScb->SCB_Status = STATUS_QUEUED;
554: pScb->SCB_HaStat = HOST_OK;
555: pScb->SCB_TaStat = SCSI_OK;
556:
557: pScb->SCB_NxtStat = 0;
558: pScb->SCB_Flags = 0;
559: pScb->SCB_Target = 0;
560: pScb->SCB_Lun = 0;
561: pScb->SCB_CDBLen = 0;
562: pScb->SCB_Ident = 0;
563: pScb->SCB_TagMsg = 0;
564:
565: pScb->SCB_BufChars = 0;
566: pScb->SCB_BufCharsLeft = 0;
567:
568: pScb->SCB_Xs = NULL;
569: pScb->SCB_Tcs = NULL;
570:
571: bzero(pScb->SCB_CDB, sizeof(pScb->SCB_CDB));
572:
573: /*
574: * SCB_TagId is set at initialization and never changes
575: */
576:
577: TAILQ_INSERT_TAIL(&sc->HCS_FreeScb, pScb, SCB_ScbList);
578:
579: splx(s);
580: }
581:
582: void
583: iha_append_pend_scb(sc, pScb)
584: struct iha_softc *sc;
585: struct iha_scb *pScb;
586: {
587: /* ASSUMPTION: only called within a splbio()/splx() pair */
588:
589: if (pScb == sc->HCS_ActScb)
590: sc->HCS_ActScb = NULL;
591:
592: pScb->SCB_Status = STATUS_QUEUED;
593:
594: TAILQ_INSERT_TAIL(&sc->HCS_PendScb, pScb, SCB_ScbList);
595: }
596:
597: void
598: iha_push_pend_scb(sc, pScb)
599: struct iha_softc *sc;
600: struct iha_scb *pScb;
601: {
602: int s;
603:
604: s = splbio();
605:
606: if (pScb == sc->HCS_ActScb)
607: sc->HCS_ActScb = NULL;
608:
609: pScb->SCB_Status = STATUS_QUEUED;
610:
611: TAILQ_INSERT_HEAD(&sc->HCS_PendScb, pScb, SCB_ScbList);
612:
613: splx(s);
614: }
615:
616: /*
617: * iha_find_pend_scb - scan the pending queue for a SCB that can be
618: * processed immediately. Return NULL if none found
619: * and a pointer to the SCB if one is found. If there
620: * is an active SCB, return NULL!
621: */
622: struct iha_scb *
623: iha_find_pend_scb(sc)
624: struct iha_softc *sc;
625: {
626: struct iha_scb *pScb;
627: struct tcs *pTcs;
628: int s;
629:
630: s = splbio();
631:
632: if (sc->HCS_ActScb != NULL)
633: pScb = NULL;
634:
635: else
636: TAILQ_FOREACH(pScb, &sc->HCS_PendScb, SCB_ScbList) {
637: if ((pScb->SCB_Flags & SCSI_RESET) != 0)
638: /* ALWAYS willing to reset a device */
639: break;
640:
641: pTcs = pScb->SCB_Tcs;
642:
643: if ((pScb->SCB_TagMsg) != 0) {
644: /*
645: * A Tagged I/O. OK to start If no
646: * non-tagged I/O is active on the same
647: * target
648: */
649: if (pTcs->TCS_NonTagScb == NULL)
650: break;
651:
652: } else if (pScb->SCB_CDB[0] == REQUEST_SENSE) {
653: /*
654: * OK to do a non-tagged request sense
655: * even if a non-tagged I/O has been
656: * started, because we don't allow any
657: * disconnect during a request sense op
658: */
659: break;
660:
661: } else if (pTcs->TCS_TagCnt == 0) {
662: /*
663: * No tagged I/O active on this target,
664: * ok to start a non-tagged one if one
665: * is not already active
666: */
667: if (pTcs->TCS_NonTagScb == NULL)
668: break;
669: }
670: }
671:
672: splx(s);
673:
674: return (pScb);
675: }
676:
677: void
678: iha_mark_busy_scb(pScb)
679: struct iha_scb *pScb;
680: {
681: int s;
682:
683: s = splbio();
684:
685: pScb->SCB_Status = STATUS_BUSY;
686:
687: if (pScb->SCB_TagMsg == 0)
688: pScb->SCB_Tcs->TCS_NonTagScb = pScb;
689: else
690: pScb->SCB_Tcs->TCS_TagCnt++;
691:
692: splx(s);
693: }
694:
695: void
696: iha_append_done_scb(sc, pScb, hastat)
697: struct iha_softc *sc;
698: struct iha_scb *pScb;
699: u_int8_t hastat;
700: {
701: struct tcs *pTcs;
702: int s;
703:
704: s = splbio();
705:
706: if (pScb->SCB_Xs != NULL)
707: timeout_del(&pScb->SCB_Xs->stimeout);
708:
709: if (pScb == sc->HCS_ActScb)
710: sc->HCS_ActScb = NULL;
711:
712: pTcs = pScb->SCB_Tcs;
713:
714: if (pScb->SCB_TagMsg != 0) {
715: if (pTcs->TCS_TagCnt)
716: pTcs->TCS_TagCnt--;
717: } else if (pTcs->TCS_NonTagScb == pScb)
718: pTcs->TCS_NonTagScb = NULL;
719:
720: pScb->SCB_Status = STATUS_QUEUED;
721: pScb->SCB_HaStat = hastat;
722:
723: TAILQ_INSERT_TAIL(&sc->HCS_DoneScb, pScb, SCB_ScbList);
724:
725: splx(s);
726: }
727:
728: struct iha_scb *
729: iha_pop_done_scb(sc)
730: struct iha_softc *sc;
731: {
732: struct iha_scb *pScb;
733: int s;
734:
735: s = splbio();
736:
737: pScb = TAILQ_FIRST(&sc->HCS_DoneScb);
738:
739: if (pScb != NULL) {
740: pScb->SCB_Status = STATUS_RENT;
741: TAILQ_REMOVE(&sc->HCS_DoneScb, pScb, SCB_ScbList);
742: }
743:
744: splx(s);
745:
746: return (pScb);
747: }
748:
749: /*
750: * iha_abort_xs - find the SCB associated with the supplied xs and
751: * stop all processing on it, moving it to the done
752: * queue with the supplied host status value.
753: */
754: void
755: iha_abort_xs(sc, xs, hastat)
756: struct iha_softc *sc;
757: struct scsi_xfer *xs;
758: u_int8_t hastat;
759: {
760: struct iha_scb *pScb, *next;
761: int i, s;
762:
763: s = splbio();
764:
765: /* Check the pending queue for the SCB pointing to xs */
766:
767: for (pScb = TAILQ_FIRST(&sc->HCS_PendScb); pScb != NULL; pScb = next) {
768: next = TAILQ_NEXT(pScb, SCB_ScbList);
769: if (pScb->SCB_Xs == xs) {
770: TAILQ_REMOVE(&sc->HCS_PendScb, pScb, SCB_ScbList);
771: iha_append_done_scb(sc, pScb, hastat);
772: splx(s);
773: return;
774: }
775: }
776:
777: /*
778: * If that didn't work, check all BUSY/SELECTING SCB's for one
779: * pointing to xs
780: */
781:
782: for (i = 0, pScb = sc->HCS_Scb; i < IHA_MAX_SCB; i++, pScb++)
783: switch (pScb->SCB_Status) {
784: case STATUS_BUSY:
785: case STATUS_SELECT:
786: if (pScb->SCB_Xs == xs) {
787: iha_append_done_scb(sc, pScb, hastat);
788: splx(s);
789: return;
790: }
791: break;
792: default:
793: break;
794: }
795:
796: splx(s);
797: }
798:
799: /*
800: * iha_bad_seq - a SCSI bus phase was encountered out of the
801: * correct/expected sequence. Reset the SCSI bus.
802: */
803: void
804: iha_bad_seq(sc)
805: struct iha_softc *sc;
806: {
807: struct iha_scb *pScb = sc->HCS_ActScb;
808:
809: if (pScb != NULL)
810: iha_append_done_scb(sc, pScb, HOST_BAD_PHAS);
811:
812: iha_reset_scsi_bus(sc);
813: iha_reset_chip(sc, sc->sc_iot, sc->sc_ioh);
814: }
815:
816: /*
817: * iha_push_sense_request - obtain auto sense data by pushing the
818: * SCB needing it back onto the pending
819: * queue with a REQUEST_SENSE CDB.
820: */
821: int
822: iha_push_sense_request(sc, pScb)
823: struct iha_softc *sc;
824: struct iha_scb *pScb;
825: {
826: struct scsi_sense *sensecmd;
827: int error;
828:
829: /* First sync & unload any existing DataDma and SGDma maps */
830: if ((pScb->SCB_Flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) != 0) {
831: bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma,
832: 0, pScb->SCB_BufChars,
833: ((pScb->SCB_Flags & SCSI_DATA_IN) ?
834: BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
835: bus_dmamap_unload(sc->sc_dmat, pScb->SCB_DataDma);
836: /* Don't unload this map again until it is reloaded */
837: pScb->SCB_Flags &= ~(SCSI_DATA_IN | SCSI_DATA_OUT);
838: }
839: if ((pScb->SCB_Flags & FLAG_SG) != 0) {
840: bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma,
841: 0, sizeof(pScb->SCB_SGList),
842: BUS_DMASYNC_POSTWRITE);
843: bus_dmamap_unload(sc->sc_dmat, pScb->SCB_SGDma);
844: /* Don't unload this map again until it is reloaded */
845: pScb->SCB_Flags &= ~FLAG_SG;
846: }
847:
848: pScb->SCB_BufChars = sizeof(pScb->SCB_ScsiSenseData);
849: pScb->SCB_BufCharsLeft = sizeof(pScb->SCB_ScsiSenseData);
850: bzero(&pScb->SCB_ScsiSenseData, sizeof(pScb->SCB_ScsiSenseData));
851:
852: error = bus_dmamap_load(sc->sc_dmat, pScb->SCB_DataDma,
853: &pScb->SCB_ScsiSenseData,
854: sizeof(pScb->SCB_ScsiSenseData), NULL,
855: (pScb->SCB_Flags & SCSI_NOSLEEP) ?
856: BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
857: if (error) {
858: sc_print_addr(pScb->SCB_Xs->sc_link);
859: printf("error %d loading request sense buffer dma map\n",
860: error);
861: return (error);
862: }
863: bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma,
864: 0, pScb->SCB_BufChars, BUS_DMASYNC_PREREAD);
865:
866: /* Save _POLL and _NOSLEEP flags. */
867: pScb->SCB_Flags &= SCSI_POLL | SCSI_NOSLEEP;
868: pScb->SCB_Flags |= FLAG_RSENS | SCSI_DATA_IN;
869:
870: error = iha_setup_sg_list(sc, pScb);
871: if (error)
872: return (error);
873:
874: pScb->SCB_Ident &= ~MSG_IDENTIFY_DISCFLAG;
875:
876: pScb->SCB_TagMsg = 0;
877: pScb->SCB_TaStat = SCSI_OK;
878:
879: bzero(pScb->SCB_CDB, sizeof(pScb->SCB_CDB));
880:
881: sensecmd = (struct scsi_sense *)pScb->SCB_CDB;
882: pScb->SCB_CDBLen = sizeof(*sensecmd);
883: sensecmd->opcode = REQUEST_SENSE;
884: sensecmd->byte2 = pScb->SCB_Xs->sc_link->lun << 5;
885: sensecmd->length = sizeof(pScb->SCB_ScsiSenseData);
886:
887: if ((pScb->SCB_Flags & SCSI_POLL) == 0)
888: timeout_add(&pScb->SCB_Xs->stimeout,
889: (pScb->SCB_Xs->timeout/1000) * hz);
890:
891: iha_push_pend_scb(sc, pScb);
892:
893: return (0);
894: }
895:
896: /*
897: * iha_main - process the active SCB, taking one off pending and making it
898: * active if necessary, and any done SCB's created as
899: * a result until there are no interrupts pending and no pending
900: * SCB's that can be started.
901: */
902: void
903: iha_main(sc, iot, ioh)
904: struct iha_softc *sc;
905: bus_space_tag_t iot;
906: bus_space_handle_t ioh;
907: {
908: struct iha_scb *pScb;
909:
910: for (;;) {
911: iha_scsi_label:
912: iha_scsi(sc, iot, ioh);
913:
914: while ((pScb = iha_pop_done_scb(sc)) != NULL) {
915:
916: switch (pScb->SCB_TaStat) {
917: case SCSI_TERMINATED:
918: case SCSI_ACA_ACTIVE:
919: case SCSI_CHECK:
920: pScb->SCB_Tcs->TCS_Flags &=
921: ~(FLAG_SYNC_DONE | FLAG_WIDE_DONE);
922:
923: if ((pScb->SCB_Flags & FLAG_RSENS) != 0)
924: /* Check condition on check condition*/
925: pScb->SCB_HaStat = HOST_BAD_PHAS;
926: else if (iha_push_sense_request(sc, pScb) != 0)
927: /* Could not push sense request */
928: pScb->SCB_HaStat = HOST_BAD_PHAS;
929: else
930: /* REQUEST SENSE ready to process */
931: goto iha_scsi_label;
932: break;
933:
934: default:
935: if ((pScb->SCB_Flags & FLAG_RSENS) != 0)
936: /*
937: * Return the original SCSI_CHECK, not
938: * the status of the request sense
939: * command!
940: */
941: pScb->SCB_TaStat = SCSI_CHECK;
942: break;
943: }
944:
945: iha_done_scb(sc, pScb);
946: }
947:
948: /*
949: * If there are no interrupts pending, or we can't start
950: * a pending sc, break out of the for(;;). Otherwise
951: * continue the good work with another call to
952: * iha_scsi().
953: */
954: if (((bus_space_read_1(iot, ioh, TUL_STAT0) & INTPD) == 0)
955: && (iha_find_pend_scb(sc) == NULL))
956: break;
957: }
958: }
959:
960: /*
961: * iha_scsi - service any outstanding interrupts. If there are none, try to
962: * start another SCB currently in the pending queue.
963: */
964: void
965: iha_scsi(sc, iot, ioh)
966: struct iha_softc *sc;
967: bus_space_tag_t iot;
968: bus_space_handle_t ioh;
969: {
970: struct iha_scb *pScb;
971: struct tcs *pTcs;
972: u_int8_t stat;
973: int i;
974:
975: /* service pending interrupts asap */
976:
977: stat = bus_space_read_1(iot, ioh, TUL_STAT0);
978: if ((stat & INTPD) != 0) {
979: sc->HCS_JSStatus0 = stat;
980: sc->HCS_JSStatus1 = bus_space_read_1(iot, ioh, TUL_STAT1);
981: sc->HCS_JSInt = bus_space_read_1(iot, ioh, TUL_SISTAT);
982:
983: sc->HCS_Phase = sc->HCS_JSStatus0 & PH_MASK;
984:
985: if ((sc->HCS_JSInt & SRSTD) != 0) {
986: iha_reset_scsi_bus(sc);
987: return;
988: }
989:
990: if ((sc->HCS_JSInt & RSELED) != 0) {
991: iha_resel(sc, iot, ioh);
992: return;
993: }
994:
995: if ((sc->HCS_JSInt & (STIMEO | DISCD)) != 0) {
996: iha_busfree(sc, iot, ioh);
997: return;
998: }
999:
1000: if ((sc->HCS_JSInt & (SCMDN | SBSRV)) != 0) {
1001: iha_next_state(sc, iot, ioh);
1002: return;
1003: }
1004:
1005: if ((sc->HCS_JSInt & SELED) != 0)
1006: iha_set_ssig(iot, ioh, 0, 0);
1007: }
1008:
1009: /*
1010: * There were no interrupts pending which required action elsewhere, so
1011: * see if it is possible to start the selection phase on a pending SCB
1012: */
1013: if ((pScb = iha_find_pend_scb(sc)) == NULL)
1014: return;
1015:
1016: pTcs = pScb->SCB_Tcs;
1017:
1018: /* program HBA's SCSI ID & target SCSI ID */
1019: bus_space_write_1(iot, ioh, TUL_SID,
1020: (sc->sc_link.adapter_target << 4) | pScb->SCB_Target);
1021:
1022: if ((pScb->SCB_Flags & SCSI_RESET) == 0) {
1023: bus_space_write_1(iot, ioh, TUL_SYNCM, pTcs->TCS_JS_Period);
1024:
1025: if (((pTcs->TCS_Flags & FLAG_NO_NEG_WIDE) == 0)
1026: ||
1027: ((pTcs->TCS_Flags & FLAG_NO_NEG_SYNC) == 0))
1028: iha_select(sc, iot, ioh, pScb, SELATNSTOP);
1029:
1030: else if (pScb->SCB_TagMsg != 0)
1031: iha_select(sc, iot, ioh, pScb, SEL_ATN3);
1032:
1033: else
1034: iha_select(sc, iot, ioh, pScb, SEL_ATN);
1035:
1036: } else {
1037: iha_select(sc, iot, ioh, pScb, SELATNSTOP);
1038: pScb->SCB_NxtStat = 8;
1039: }
1040:
1041: if ((pScb->SCB_Flags & SCSI_POLL) != 0) {
1042: for (i = pScb->SCB_Xs->timeout; i > 0; i--) {
1043: if (iha_wait(sc, iot, ioh, NO_OP) == -1)
1044: break;
1045: if (iha_next_state(sc, iot, ioh) == -1)
1046: break;
1047: delay(1000); /* Only happens in boot, so it's ok */
1048: }
1049:
1050: /*
1051: * Since done queue processing not done until AFTER this
1052: * function returns, pScb is on the done queue, not
1053: * the free queue at this point and still has valid data
1054: *
1055: * Conversely, xs->error has not been set yet
1056: */
1057: if (i == 0)
1058: iha_timeout(pScb);
1059:
1060: else if ((pScb->SCB_CDB[0] == INQUIRY)
1061: && (pScb->SCB_Lun == 0)
1062: && (pScb->SCB_HaStat == HOST_OK)
1063: && (pScb->SCB_TaStat == SCSI_OK))
1064: iha_print_info(sc, pScb->SCB_Target);
1065: }
1066: }
1067:
1068: /*
1069: * iha_data_over_run - return HOST_OK for all SCSI opcodes where BufCharsLeft
1070: * is an 'Allocation Length'. All other SCSI opcodes
1071: * get HOST_DO_DU as they SHOULD have xferred all the
1072: * data requested.
1073: *
1074: * The list of opcodes using 'Allocation Length' was
1075: * found by scanning all the SCSI-3 T10 drafts. See
1076: * www.t10.org for the curious with a .pdf reader.
1077: */
1078: u_int8_t
1079: iha_data_over_run(pScb)
1080: struct iha_scb *pScb;
1081: {
1082: switch (pScb->SCB_CDB[0]) {
1083: case 0x03: /* Request Sense SPC-2 */
1084: case 0x12: /* Inquiry SPC-2 */
1085: case 0x1a: /* Mode Sense (6 byte version) SPC-2 */
1086: case 0x1c: /* Receive Diagnostic Results SPC-2 */
1087: case 0x23: /* Read Format Capacities MMC-2 */
1088: case 0x29: /* Read Generation SBC */
1089: case 0x34: /* Read Position SSC-2 */
1090: case 0x37: /* Read Defect Data SBC */
1091: case 0x3c: /* Read Buffer SPC-2 */
1092: case 0x42: /* Read Sub Channel MMC-2 */
1093: case 0x43: /* Read TOC/PMA/ATIP MMC */
1094:
1095: /* XXX - 2 with same opcode of 0x44? */
1096: case 0x44: /* Read Header/Read Density Suprt MMC/SSC*/
1097:
1098: case 0x46: /* Get Configuration MMC-2 */
1099: case 0x4a: /* Get Event/Status Notification MMC-2 */
1100: case 0x4d: /* Log Sense SPC-2 */
1101: case 0x51: /* Read Disc Information MMC */
1102: case 0x52: /* Read Track Information MMC */
1103: case 0x59: /* Read Master CUE MMC */
1104: case 0x5a: /* Mode Sense (10 byte version) SPC-2 */
1105: case 0x5c: /* Read Buffer Capacity MMC */
1106: case 0x5e: /* Persistent Reserve In SPC-2 */
1107: case 0x84: /* Receive Copy Results SPC-2 */
1108: case 0xa0: /* Report LUNs SPC-2 */
1109: case 0xa3: /* Various Report requests SBC-2/SCC-2*/
1110: case 0xa4: /* Report Key MMC-2 */
1111: case 0xad: /* Read DVD Structure MMC-2 */
1112: case 0xb4: /* Read Element Status (Attached) SMC */
1113: case 0xb5: /* Request Volume Element Address SMC */
1114: case 0xb7: /* Read Defect Data (12 byte ver.) SBC */
1115: case 0xb8: /* Read Element Status (Independ.) SMC */
1116: case 0xba: /* Report Redundancy SCC-2 */
1117: case 0xbd: /* Mechanism Status MMC */
1118: case 0xbe: /* Report Basic Redundancy SCC-2 */
1119:
1120: return (HOST_OK);
1121: break;
1122:
1123: default:
1124: return (HOST_DO_DU);
1125: break;
1126: }
1127: }
1128:
1129: /*
1130: * iha_next_state - process the current SCB as requested in its
1131: * SCB_NxtStat member.
1132: */
1133: int
1134: iha_next_state(sc, iot, ioh)
1135: struct iha_softc *sc;
1136: bus_space_tag_t iot;
1137: bus_space_handle_t ioh;
1138: {
1139: if (sc->HCS_ActScb == NULL)
1140: return (-1);
1141:
1142: switch (sc->HCS_ActScb->SCB_NxtStat) {
1143: case 1:
1144: if (iha_state_1(sc, iot, ioh) == 3)
1145: goto state_3;
1146: break;
1147:
1148: case 2:
1149: switch (iha_state_2(sc, iot, ioh)) {
1150: case 3: goto state_3;
1151: case 4: goto state_4;
1152: default: break;
1153: }
1154: break;
1155:
1156: case 3:
1157: state_3:
1158: if (iha_state_3(sc, iot, ioh) == 4)
1159: goto state_4;
1160: break;
1161:
1162: case 4:
1163: state_4:
1164: switch (iha_state_4(sc, iot, ioh)) {
1165: case 0: return (0);
1166: case 6: goto state_6;
1167: default: break;
1168: }
1169: break;
1170:
1171: case 5:
1172: switch (iha_state_5(sc, iot, ioh)) {
1173: case 4: goto state_4;
1174: case 6: goto state_6;
1175: default: break;
1176: }
1177: break;
1178:
1179: case 6:
1180: state_6:
1181: iha_state_6(sc, iot, ioh);
1182: break;
1183:
1184: case 8:
1185: iha_state_8(sc, iot, ioh);
1186: break;
1187:
1188: default:
1189: #ifdef IHA_DEBUG_STATE
1190: sc_print_addr(sc->HCS_ActScb->SCB_Xs->sc_link);
1191: printf("[debug] -unknown state: %i-\n",
1192: sc->HCS_ActScb->SCB_NxtStat);
1193: #endif
1194: iha_bad_seq(sc);
1195: break;
1196: }
1197:
1198: return (-1);
1199: }
1200:
1201: /*
1202: * iha_state_1 - selection is complete after a SELATNSTOP. If the target
1203: * has put the bus into MSG_OUT phase start wide/sync
1204: * negotiation. Otherwise clear the FIFO and go to state 3,
1205: * which will send the SCSI CDB to the target.
1206: */
1207: int
1208: iha_state_1(sc, iot, ioh)
1209: struct iha_softc *sc;
1210: bus_space_tag_t iot;
1211: bus_space_handle_t ioh;
1212: {
1213: struct iha_scb *pScb = sc->HCS_ActScb;
1214: struct tcs *pTcs;
1215: u_int16_t flags;
1216:
1217: iha_mark_busy_scb(pScb);
1218:
1219: pTcs = pScb->SCB_Tcs;
1220:
1221: bus_space_write_1(iot, ioh, TUL_SCONFIG0, pTcs->TCS_SConfig0);
1222:
1223: /*
1224: * If we are in PHASE_MSG_OUT, send
1225: * a) IDENT message (with tags if appropriate)
1226: * b) WDTR if the target is configured to negotiate wide xfers
1227: * ** OR **
1228: * c) SDTR if the target is configured to negotiate sync xfers
1229: * but not wide ones
1230: *
1231: * If we are NOT, then the target is not asking for anything but
1232: * the data/command, so go straight to state 3.
1233: */
1234: if (sc->HCS_Phase == PHASE_MSG_OUT) {
1235: bus_space_write_1(iot, ioh, TUL_SCTRL1, (ESBUSIN | EHRSL));
1236: bus_space_write_1(iot, ioh, TUL_SFIFO, pScb->SCB_Ident);
1237:
1238: if (pScb->SCB_TagMsg != 0) {
1239: bus_space_write_1(iot, ioh, TUL_SFIFO,
1240: pScb->SCB_TagMsg);
1241: bus_space_write_1(iot, ioh, TUL_SFIFO,
1242: pScb->SCB_TagId);
1243: }
1244:
1245: flags = pTcs->TCS_Flags;
1246: if ((flags & FLAG_NO_NEG_WIDE) == 0) {
1247: if (iha_msgout_wdtr(sc, iot, ioh) == -1)
1248: return (-1);
1249: } else if ((flags & FLAG_NO_NEG_SYNC) == 0) {
1250: if (iha_msgout_sdtr(sc, iot, ioh) == -1)
1251: return (-1);
1252: }
1253:
1254: } else {
1255: bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
1256: iha_set_ssig(iot, ioh, REQ | BSY | SEL | ATN, 0);
1257: }
1258:
1259: return (3);
1260: }
1261:
1262: /*
1263: * iha_state_2 - selection is complete after a SEL_ATN or SEL_ATN3. If the SCSI
1264: * CDB has already been send, go to state 4 to start the data
1265: * xfer. Otherwise reset the FIFO and go to state 3, sending
1266: * the SCSI CDB.
1267: */
1268: int
1269: iha_state_2(sc, iot, ioh)
1270: struct iha_softc *sc;
1271: bus_space_tag_t iot;
1272: bus_space_handle_t ioh;
1273: {
1274: struct iha_scb *pScb = sc->HCS_ActScb;
1275:
1276: iha_mark_busy_scb(pScb);
1277:
1278: bus_space_write_1(iot, ioh, TUL_SCONFIG0, pScb->SCB_Tcs->TCS_SConfig0);
1279:
1280: if ((sc->HCS_JSStatus1 & CPDNE) != 0)
1281: return (4);
1282:
1283: bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
1284:
1285: iha_set_ssig(iot, ioh, REQ | BSY | SEL | ATN, 0);
1286:
1287: return (3);
1288: }
1289:
1290: /*
1291: * iha_state_3 - send the SCSI CDB to the target, processing any status
1292: * or other messages received until that is done or
1293: * abandoned.
1294: */
1295: int
1296: iha_state_3(sc, iot, ioh)
1297: struct iha_softc *sc;
1298: bus_space_tag_t iot;
1299: bus_space_handle_t ioh;
1300: {
1301: struct iha_scb *pScb = sc->HCS_ActScb;
1302: u_int16_t flags;
1303:
1304: for (;;)
1305: switch (sc->HCS_Phase) {
1306: case PHASE_CMD_OUT:
1307: bus_space_write_multi_1(iot, ioh, TUL_SFIFO,
1308: pScb->SCB_CDB, pScb->SCB_CDBLen);
1309: if (iha_wait(sc, iot, ioh, XF_FIFO_OUT) == -1)
1310: return (-1);
1311: else if (sc->HCS_Phase == PHASE_CMD_OUT) {
1312: iha_bad_seq(sc);
1313: return (-1);
1314: } else
1315: return (4);
1316:
1317: case PHASE_MSG_IN:
1318: pScb->SCB_NxtStat = 3;
1319: if (iha_msgin(sc, iot, ioh) == -1)
1320: return (-1);
1321: break;
1322:
1323: case PHASE_STATUS_IN:
1324: if (iha_status_msg(sc, iot, ioh) == -1)
1325: return (-1);
1326: break;
1327:
1328: case PHASE_MSG_OUT:
1329: flags = pScb->SCB_Tcs->TCS_Flags;
1330: if ((flags & FLAG_NO_NEG_SYNC) != 0) {
1331: if (iha_msgout(sc, iot, ioh, MSG_NOOP) == -1)
1332: return (-1);
1333: } else if (iha_msgout_sdtr(sc, iot, ioh) == -1)
1334: return (-1);
1335: break;
1336:
1337: default:
1338: #ifdef IHA_DEBUG_STATE
1339: sc_print_addr(pScb->SCB_Xs->sc_link);
1340: printf("[debug] -s3- bad phase = %d\n", sc->HCS_Phase);
1341: #endif
1342: iha_bad_seq(sc);
1343: return (-1);
1344: }
1345: }
1346:
1347: /*
1348: * iha_state_4 - start a data xfer. Handle any bus state
1349: * transitions until PHASE_DATA_IN/_OUT
1350: * or the attempt is abandoned. If there is
1351: * no data to xfer, go to state 6 and finish
1352: * processing the current SCB.
1353: */
1354: int
1355: iha_state_4(sc, iot, ioh)
1356: struct iha_softc *sc;
1357: bus_space_tag_t iot;
1358: bus_space_handle_t ioh;
1359: {
1360: struct iha_scb *pScb = sc->HCS_ActScb;
1361:
1362: if ((pScb->SCB_Flags & FLAG_DIR) == FLAG_DIR)
1363: return (6); /* Both dir flags set => NO xfer was requested */
1364:
1365: for (;;) {
1366: if (pScb->SCB_BufCharsLeft == 0)
1367: return (6);
1368:
1369: switch (sc->HCS_Phase) {
1370: case PHASE_STATUS_IN:
1371: if ((pScb->SCB_Flags & FLAG_DIR) != 0)
1372: pScb->SCB_HaStat = iha_data_over_run(pScb);
1373: if ((iha_status_msg(sc, iot, ioh)) == -1)
1374: return (-1);
1375: break;
1376:
1377: case PHASE_MSG_IN:
1378: pScb->SCB_NxtStat = 4;
1379: if (iha_msgin(sc, iot, ioh) == -1)
1380: return (-1);
1381: break;
1382:
1383: case PHASE_MSG_OUT:
1384: if ((sc->HCS_JSStatus0 & SPERR) != 0) {
1385: pScb->SCB_BufCharsLeft = 0;
1386: pScb->SCB_HaStat = HOST_SPERR;
1387: if (iha_msgout(sc, iot, ioh,
1388: MSG_INITIATOR_DET_ERR) == -1)
1389: return (-1);
1390: else
1391: return (6);
1392: } else {
1393: if (iha_msgout(sc, iot, ioh, MSG_NOOP) == -1)
1394: return (-1);
1395: }
1396: break;
1397:
1398: case PHASE_DATA_IN:
1399: return (iha_xfer_data(pScb, iot, ioh, SCSI_DATA_IN));
1400:
1401: case PHASE_DATA_OUT:
1402: return (iha_xfer_data(pScb, iot, ioh, SCSI_DATA_OUT));
1403:
1404: default:
1405: iha_bad_seq(sc);
1406: return (-1);
1407: }
1408: }
1409: }
1410:
1411: /*
1412: * iha_state_5 - handle the partial or final completion of the current
1413: * data xfer. If DMA is still active stop it. If there is
1414: * more data to xfer, go to state 4 and start the xfer.
1415: * If not go to state 6 and finish the SCB.
1416: */
1417: int
1418: iha_state_5(sc, iot, ioh)
1419: struct iha_softc *sc;
1420: bus_space_tag_t iot;
1421: bus_space_handle_t ioh;
1422: {
1423: struct iha_scb *pScb = sc->HCS_ActScb;
1424: struct iha_sg_element *pSg;
1425: u_int32_t cnt;
1426: u_int16_t period;
1427: u_int8_t stat;
1428: long xcnt; /* cannot use unsigned!! see code: if (xcnt < 0) */
1429:
1430: cnt = bus_space_read_4(iot, ioh, TUL_STCNT0) & TCNT;
1431:
1432: /*
1433: * Stop any pending DMA activity and check for parity error.
1434: */
1435:
1436: if ((bus_space_read_1(iot, ioh, TUL_DCMD) & XDIR) != 0) {
1437: /* Input Operation */
1438: if ((sc->HCS_JSStatus0 & SPERR) != 0)
1439: pScb->SCB_HaStat = HOST_SPERR;
1440:
1441: if ((bus_space_read_1(iot, ioh, TUL_ISTUS1) & XPEND) != 0) {
1442: bus_space_write_1(iot, ioh, TUL_DCTRL0,
1443: bus_space_read_1(iot, ioh, TUL_DCTRL0) | SXSTP);
1444: while (bus_space_read_1(iot, ioh, TUL_ISTUS1) & XPEND)
1445: ;
1446: }
1447:
1448: } else {
1449: /* Output Operation */
1450: if ((sc->HCS_JSStatus1 & SXCMP) == 0) {
1451: period = pScb->SCB_Tcs->TCS_JS_Period;
1452: if ((period & PERIOD_WIDE_SCSI) != 0)
1453: cnt += (bus_space_read_1(iot, ioh,
1454: TUL_SFIFOCNT) & FIFOC) << 1;
1455: else
1456: cnt += (bus_space_read_1(iot, ioh,
1457: TUL_SFIFOCNT) & FIFOC);
1458: }
1459:
1460: if ((bus_space_read_1(iot, ioh, TUL_ISTUS1) & XPEND) != 0) {
1461: bus_space_write_1(iot, ioh, TUL_DCMD, ABTXFR);
1462: do
1463: stat = bus_space_read_1(iot, ioh, TUL_ISTUS0);
1464: while ((stat & DABT) == 0);
1465: }
1466:
1467: if ((cnt == 1) && (sc->HCS_Phase == PHASE_DATA_OUT)) {
1468: if (iha_wait(sc, iot, ioh, XF_FIFO_OUT) == -1)
1469: return (-1);
1470: cnt = 0;
1471:
1472: } else if ((sc->HCS_JSStatus1 & SXCMP) == 0)
1473: bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
1474: }
1475:
1476: if (cnt == 0) {
1477: pScb->SCB_BufCharsLeft = 0;
1478: return (6);
1479: }
1480:
1481: /* Update active data pointer and restart the I/O at the new point */
1482:
1483: xcnt = pScb->SCB_BufCharsLeft - cnt; /* xcnt == bytes xferred */
1484: pScb->SCB_BufCharsLeft = cnt; /* cnt == bytes left */
1485:
1486: bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma,
1487: 0, sizeof(pScb->SCB_SGList), BUS_DMASYNC_POSTWRITE);
1488:
1489: if ((pScb->SCB_Flags & FLAG_SG) != 0) {
1490: pSg = &pScb->SCB_SGList[pScb->SCB_SGIdx];
1491: for (; pScb->SCB_SGIdx < pScb->SCB_SGCount; pSg++, pScb->SCB_SGIdx++) {
1492: xcnt -= pSg->SG_Len;
1493: if (xcnt < 0) {
1494: xcnt += pSg->SG_Len;
1495:
1496: pSg->SG_Addr += xcnt;
1497: pSg->SG_Len -= xcnt;
1498:
1499: bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma,
1500: 0, sizeof(pScb->SCB_SGList),
1501: BUS_DMASYNC_PREWRITE);
1502:
1503: return (4);
1504: }
1505: }
1506: return (6);
1507:
1508: }
1509:
1510: return (4);
1511: }
1512:
1513: /*
1514: * iha_state_6 - finish off the active scb (may require several
1515: * iterations if PHASE_MSG_IN) and return -1 to indicate
1516: * the bus is free.
1517: */
1518: int
1519: iha_state_6(sc, iot, ioh)
1520: struct iha_softc *sc;
1521: bus_space_tag_t iot;
1522: bus_space_handle_t ioh;
1523: {
1524: for (;;)
1525: switch (sc->HCS_Phase) {
1526: case PHASE_STATUS_IN:
1527: if (iha_status_msg(sc, iot, ioh) == -1)
1528: return (-1);
1529: break;
1530:
1531: case PHASE_MSG_IN:
1532: sc->HCS_ActScb->SCB_NxtStat = 6;
1533: if ((iha_msgin(sc, iot, ioh)) == -1)
1534: return (-1);
1535: break;
1536:
1537: case PHASE_MSG_OUT:
1538: if ((iha_msgout(sc, iot, ioh, MSG_NOOP)) == -1)
1539: return (-1);
1540: break;
1541:
1542: case PHASE_DATA_IN:
1543: if (iha_xpad_in(sc, iot, ioh) == -1)
1544: return (-1);
1545: break;
1546:
1547: case PHASE_DATA_OUT:
1548: if (iha_xpad_out(sc, iot, ioh) == -1)
1549: return (-1);
1550: break;
1551:
1552: default:
1553: iha_bad_seq(sc);
1554: return (-1);
1555: }
1556: }
1557:
1558: /*
1559: * iha_state_8 - reset the active device and all busy SCBs using it
1560: */
1561: int
1562: iha_state_8(sc, iot, ioh)
1563: struct iha_softc *sc;
1564: bus_space_tag_t iot;
1565: bus_space_handle_t ioh;
1566: {
1567: struct iha_scb *pScb;
1568: u_int32_t i;
1569: u_int8_t tar;
1570:
1571: if (sc->HCS_Phase == PHASE_MSG_OUT) {
1572: bus_space_write_1(iot, ioh, TUL_SFIFO, MSG_BUS_DEV_RESET);
1573:
1574: pScb = sc->HCS_ActScb;
1575:
1576: /* This SCB finished correctly -- resetting the device */
1577: iha_append_done_scb(sc, pScb, HOST_OK);
1578:
1579: iha_reset_tcs(pScb->SCB_Tcs, sc->HCS_SConf1);
1580:
1581: tar = pScb->SCB_Target;
1582: for (i = 0, pScb = sc->HCS_Scb; i < IHA_MAX_SCB; i++, pScb++)
1583: if (pScb->SCB_Target == tar)
1584: switch (pScb->SCB_Status) {
1585: case STATUS_BUSY:
1586: iha_append_done_scb(sc,
1587: pScb, HOST_DEV_RST);
1588: break;
1589:
1590: case STATUS_SELECT:
1591: iha_push_pend_scb(sc, pScb);
1592: break;
1593:
1594: default:
1595: break;
1596: }
1597:
1598: sc->HCS_Flags |= FLAG_EXPECT_DISC;
1599:
1600: if (iha_wait(sc, iot, ioh, XF_FIFO_OUT) == -1)
1601: return (-1);
1602: }
1603:
1604: iha_bad_seq(sc);
1605: return (-1);
1606: }
1607:
1608: /*
1609: * iha_xfer_data - initiate the DMA xfer of the data
1610: */
1611: int
1612: iha_xfer_data(pScb, iot, ioh, direction)
1613: struct iha_scb *pScb;
1614: bus_space_tag_t iot;
1615: bus_space_handle_t ioh;
1616: int direction;
1617: {
1618: u_int32_t xferaddr, xferlen;
1619: u_int8_t xfertype;
1620:
1621: if ((pScb->SCB_Flags & FLAG_DIR) != direction)
1622: return (6); /* wrong direction, abandon I/O */
1623:
1624: bus_space_write_4(iot, ioh, TUL_STCNT0, pScb->SCB_BufCharsLeft);
1625:
1626: if ((pScb->SCB_Flags & FLAG_SG) == 0) {
1627: xferaddr = pScb->SCB_DataDma->dm_segs[0].ds_addr
1628: + (pScb->SCB_BufChars - pScb->SCB_BufCharsLeft);
1629: xferlen = pScb->SCB_BufCharsLeft;
1630: xfertype = (direction == SCSI_DATA_IN) ? ST_X_IN : ST_X_OUT;
1631:
1632: } else {
1633: xferaddr = pScb->SCB_SGDma->dm_segs[0].ds_addr
1634: + (pScb->SCB_SGIdx * sizeof(struct iha_sg_element));
1635: xferlen = (pScb->SCB_SGCount - pScb->SCB_SGIdx)
1636: * sizeof(struct iha_sg_element);
1637: xfertype = (direction == SCSI_DATA_IN) ? ST_SG_IN : ST_SG_OUT;
1638: }
1639:
1640: bus_space_write_4(iot, ioh, TUL_DXC, xferlen);
1641: bus_space_write_4(iot, ioh, TUL_DXPA, xferaddr);
1642: bus_space_write_1(iot, ioh, TUL_DCMD, xfertype);
1643:
1644: bus_space_write_1(iot, ioh, TUL_SCMD,
1645: (direction == SCSI_DATA_IN) ? XF_DMA_IN : XF_DMA_OUT);
1646:
1647: pScb->SCB_NxtStat = 5;
1648:
1649: return (0);
1650: }
1651:
1652: int
1653: iha_xpad_in(sc, iot, ioh)
1654: struct iha_softc *sc;
1655: bus_space_tag_t iot;
1656: bus_space_handle_t ioh;
1657: {
1658: struct iha_scb *pScb = sc->HCS_ActScb;
1659:
1660: if ((pScb->SCB_Flags & FLAG_DIR) != 0)
1661: pScb->SCB_HaStat = HOST_DO_DU;
1662:
1663: for (;;) {
1664: if ((pScb->SCB_Tcs->TCS_JS_Period & PERIOD_WIDE_SCSI) != 0)
1665: bus_space_write_4(iot, ioh, TUL_STCNT0, 2);
1666: else
1667: bus_space_write_4(iot, ioh, TUL_STCNT0, 1);
1668:
1669: switch (iha_wait(sc, iot, ioh, XF_FIFO_IN)) {
1670: case -1:
1671: return (-1);
1672:
1673: case PHASE_DATA_IN:
1674: bus_space_read_1(iot, ioh, TUL_SFIFO);
1675: break;
1676:
1677: default:
1678: bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
1679: return (6);
1680: }
1681: }
1682: }
1683:
1684: int
1685: iha_xpad_out(sc, iot, ioh)
1686: struct iha_softc *sc;
1687: bus_space_tag_t iot;
1688: bus_space_handle_t ioh;
1689: {
1690: struct iha_scb *pScb = sc->HCS_ActScb;
1691:
1692: if ((pScb->SCB_Flags & FLAG_DIR) != 0)
1693: pScb->SCB_HaStat = HOST_DO_DU;
1694:
1695: for (;;) {
1696: if ((pScb->SCB_Tcs->TCS_JS_Period & PERIOD_WIDE_SCSI) != 0)
1697: bus_space_write_4(iot, ioh, TUL_STCNT0, 2);
1698: else
1699: bus_space_write_4(iot, ioh, TUL_STCNT0, 1);
1700:
1701: bus_space_write_1(iot, ioh, TUL_SFIFO, 0);
1702:
1703: switch (iha_wait(sc, iot, ioh, XF_FIFO_OUT)) {
1704: case -1:
1705: return (-1);
1706:
1707: case PHASE_DATA_OUT:
1708: break;
1709:
1710: default:
1711: /* Disable wide CPU to allow read 16 bits */
1712: bus_space_write_1(iot, ioh, TUL_SCTRL1, EHRSL);
1713: bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
1714: return (6);
1715: }
1716: }
1717: }
1718:
1719: int
1720: iha_status_msg(sc, iot, ioh)
1721: struct iha_softc *sc;
1722: bus_space_tag_t iot;
1723: bus_space_handle_t ioh;
1724: {
1725: struct iha_scb *pScb;
1726: u_int8_t msg;
1727: int phase;
1728:
1729: if ((phase = iha_wait(sc, iot, ioh, CMD_COMP)) == -1)
1730: return (-1);
1731:
1732: pScb = sc->HCS_ActScb;
1733:
1734: pScb->SCB_TaStat = bus_space_read_1(iot, ioh, TUL_SFIFO);
1735:
1736: if (phase == PHASE_MSG_OUT) {
1737: if ((sc->HCS_JSStatus0 & SPERR) == 0)
1738: bus_space_write_1(iot, ioh, TUL_SFIFO,
1739: MSG_NOOP);
1740: else
1741: bus_space_write_1(iot, ioh, TUL_SFIFO,
1742: MSG_PARITY_ERROR);
1743:
1744: return (iha_wait(sc, iot, ioh, XF_FIFO_OUT));
1745:
1746: } else if (phase == PHASE_MSG_IN) {
1747: msg = bus_space_read_1(iot, ioh, TUL_SFIFO);
1748:
1749: if ((sc->HCS_JSStatus0 & SPERR) != 0)
1750: switch (iha_wait(sc, iot, ioh, MSG_ACCEPT)) {
1751: case -1:
1752: return (-1);
1753: case PHASE_MSG_OUT:
1754: bus_space_write_1(iot, ioh, TUL_SFIFO,
1755: MSG_PARITY_ERROR);
1756: return (iha_wait(sc, iot, ioh, XF_FIFO_OUT));
1757: default:
1758: iha_bad_seq(sc);
1759: return (-1);
1760: }
1761:
1762: if (msg == MSG_CMDCOMPLETE) {
1763: if ((pScb->SCB_TaStat
1764: & (SCSI_INTERM | SCSI_BUSY)) == SCSI_INTERM) {
1765: iha_bad_seq(sc);
1766: return (-1);
1767: }
1768: sc->HCS_Flags |= FLAG_EXPECT_DONE_DISC;
1769: bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
1770: return (iha_wait(sc, iot, ioh, MSG_ACCEPT));
1771: }
1772:
1773: if ((msg == MSG_LINK_CMD_COMPLETE)
1774: || (msg == MSG_LINK_CMD_COMPLETEF)) {
1775: if ((pScb->SCB_TaStat
1776: & (SCSI_INTERM | SCSI_BUSY)) == SCSI_INTERM)
1777: return (iha_wait(sc, iot, ioh, MSG_ACCEPT));
1778: }
1779: }
1780:
1781: iha_bad_seq(sc);
1782: return (-1);
1783: }
1784:
1785: /*
1786: * iha_busfree - SCSI bus free detected as a result of a TIMEOUT or
1787: * DISCONNECT interrupt. Reset the tulip FIFO and
1788: * SCONFIG0 and enable hardware reselect. Move any active
1789: * SCB to HCS_DoneScb list. Return an appropriate host status
1790: * if an I/O was active.
1791: */
1792: void
1793: iha_busfree(sc, iot, ioh)
1794: struct iha_softc *sc;
1795: bus_space_tag_t iot;
1796: bus_space_handle_t ioh;
1797: {
1798: struct iha_scb *pScb;
1799:
1800: bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
1801: bus_space_write_1(iot, ioh, TUL_SCONFIG0, SCONFIG0DEFAULT);
1802: bus_space_write_1(iot, ioh, TUL_SCTRL1, EHRSL);
1803:
1804: pScb = sc->HCS_ActScb;
1805:
1806: if (pScb != NULL) {
1807: if (pScb->SCB_Status == STATUS_SELECT)
1808: /* selection timeout */
1809: iha_append_done_scb(sc, pScb, HOST_SEL_TOUT);
1810: else
1811: /* Unexpected bus free */
1812: iha_append_done_scb(sc, pScb, HOST_BAD_PHAS);
1813:
1814: }
1815: }
1816:
1817: void
1818: iha_reset_scsi_bus(sc)
1819: struct iha_softc *sc;
1820: {
1821: struct iha_scb *pScb;
1822: struct tcs *pTcs;
1823: int i, s;
1824:
1825: s = splbio();
1826:
1827: iha_reset_dma(sc->sc_iot, sc->sc_ioh);
1828:
1829: for (i = 0, pScb = sc->HCS_Scb; i < IHA_MAX_SCB; i++, pScb++)
1830: switch (pScb->SCB_Status) {
1831: case STATUS_BUSY:
1832: iha_append_done_scb(sc, pScb, HOST_SCSI_RST);
1833: break;
1834:
1835: case STATUS_SELECT:
1836: iha_push_pend_scb(sc, pScb);
1837: break;
1838:
1839: default:
1840: break;
1841: }
1842:
1843: for (i = 0, pTcs = sc->HCS_Tcs; i < IHA_MAX_TARGETS; i++, pTcs++)
1844: iha_reset_tcs(pTcs, sc->HCS_SConf1);
1845:
1846: splx(s);
1847: }
1848:
1849: /*
1850: * iha_resel - handle a detected SCSI bus reselection request.
1851: */
1852: int
1853: iha_resel(sc, iot, ioh)
1854: struct iha_softc *sc;
1855: bus_space_tag_t iot;
1856: bus_space_handle_t ioh;
1857: {
1858: struct iha_scb *pScb;
1859: struct tcs *pTcs;
1860: u_int8_t tag, target, lun, msg, abortmsg;
1861:
1862: if (sc->HCS_ActScb != NULL) {
1863: if ((sc->HCS_ActScb->SCB_Status == STATUS_SELECT))
1864: iha_push_pend_scb(sc, sc->HCS_ActScb);
1865: sc->HCS_ActScb = NULL;
1866: }
1867:
1868: target = bus_space_read_1(iot, ioh, TUL_SBID);
1869: lun = bus_space_read_1(iot, ioh, TUL_SALVC) & MSG_IDENTIFY_LUNMASK;
1870:
1871: pTcs = &sc->HCS_Tcs[target];
1872:
1873: bus_space_write_1(iot, ioh, TUL_SCONFIG0, pTcs->TCS_SConfig0);
1874: bus_space_write_1(iot, ioh, TUL_SYNCM, pTcs->TCS_JS_Period);
1875:
1876: abortmsg = MSG_ABORT; /* until a valid tag has been obtained */
1877:
1878: if (pTcs->TCS_NonTagScb != NULL)
1879: /* There is a non-tagged I/O active on the target */
1880: pScb = pTcs->TCS_NonTagScb;
1881:
1882: else {
1883: /*
1884: * Since there is no active non-tagged operation
1885: * read the tag type, the tag itself, and find
1886: * the appropriate pScb by indexing HCS_Scb with
1887: * the tag.
1888: */
1889:
1890: switch (iha_wait(sc, iot, ioh, MSG_ACCEPT)) {
1891: case -1:
1892: return (-1);
1893: case PHASE_MSG_IN:
1894: bus_space_write_4(iot, ioh, TUL_STCNT0, 1);
1895: if ((iha_wait(sc, iot, ioh, XF_FIFO_IN)) == -1)
1896: return (-1);
1897: break;
1898: default:
1899: goto abort;
1900: }
1901:
1902: msg = bus_space_read_1(iot, ioh, TUL_SFIFO); /* Read Tag Msg */
1903:
1904: if ((msg < MSG_SIMPLE_Q_TAG) || (msg > MSG_ORDERED_Q_TAG))
1905: goto abort;
1906:
1907: switch (iha_wait(sc, iot, ioh, MSG_ACCEPT)) {
1908: case -1:
1909: return (-1);
1910: case PHASE_MSG_IN:
1911: bus_space_write_4(iot, ioh, TUL_STCNT0, 1);
1912: if ((iha_wait(sc, iot, ioh, XF_FIFO_IN)) == -1)
1913: return (-1);
1914: break;
1915: default:
1916: goto abort;
1917: }
1918:
1919: tag = bus_space_read_1(iot, ioh, TUL_SFIFO); /* Read Tag ID */
1920: pScb = &sc->HCS_Scb[tag];
1921:
1922: abortmsg = MSG_ABORT_TAG; /* Now that we have valdid tag! */
1923: }
1924:
1925: if ((pScb->SCB_Target != target)
1926: || (pScb->SCB_Lun != lun)
1927: || (pScb->SCB_Status != STATUS_BUSY)) {
1928: abort:
1929: iha_msgout_abort(sc, iot, ioh, abortmsg);
1930: return (-1);
1931: }
1932:
1933: sc->HCS_ActScb = pScb;
1934:
1935: if (iha_wait(sc, iot, ioh, MSG_ACCEPT) == -1)
1936: return (-1);
1937:
1938: return(iha_next_state(sc, iot, ioh));
1939: }
1940:
1941: int
1942: iha_msgin(sc, iot, ioh)
1943: struct iha_softc *sc;
1944: bus_space_tag_t iot;
1945: bus_space_handle_t ioh;
1946: {
1947: u_int16_t flags;
1948: u_int8_t msg;
1949: int phase;
1950:
1951: for (;;) {
1952: if ((bus_space_read_1(iot, ioh, TUL_SFIFOCNT) & FIFOC) > 0)
1953: bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
1954:
1955: bus_space_write_4(iot, ioh, TUL_STCNT0, 1);
1956:
1957: phase = iha_wait(sc, iot, ioh, XF_FIFO_IN);
1958: msg = bus_space_read_1(iot, ioh, TUL_SFIFO);
1959:
1960: switch (msg) {
1961: case MSG_DISCONNECT:
1962: sc->HCS_Flags |= FLAG_EXPECT_DISC;
1963: if (iha_wait(sc, iot, ioh, MSG_ACCEPT) != -1)
1964: iha_bad_seq(sc);
1965: phase = -1;
1966: break;
1967: case MSG_SAVEDATAPOINTER:
1968: case MSG_RESTOREPOINTERS:
1969: case MSG_NOOP:
1970: phase = iha_wait(sc, iot, ioh, MSG_ACCEPT);
1971: break;
1972: case MSG_MESSAGE_REJECT:
1973: /* XXX - need to clear FIFO like other 'Clear ATN'?*/
1974: iha_set_ssig(iot, ioh, REQ | BSY | SEL | ATN, 0);
1975: flags = sc->HCS_ActScb->SCB_Tcs->TCS_Flags;
1976: if ((flags & FLAG_NO_NEG_SYNC) == 0)
1977: iha_set_ssig(iot, ioh, REQ | BSY | SEL, ATN);
1978: phase = iha_wait(sc, iot, ioh, MSG_ACCEPT);
1979: break;
1980: case MSG_EXTENDED:
1981: phase = iha_msgin_extended(sc, iot, ioh);
1982: break;
1983: case MSG_IGN_WIDE_RESIDUE:
1984: phase = iha_msgin_ignore_wid_resid(sc, iot, ioh);
1985: break;
1986: case MSG_CMDCOMPLETE:
1987: sc->HCS_Flags |= FLAG_EXPECT_DONE_DISC;
1988: bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
1989: phase = iha_wait(sc, iot, ioh, MSG_ACCEPT);
1990: if (phase != -1) {
1991: iha_bad_seq(sc);
1992: return (-1);
1993: }
1994: break;
1995: default:
1996: #ifdef IHA_DEBUG_STATE
1997: printf("[debug] iha_msgin: bad msg type: %d\n", msg);
1998: #endif
1999: phase = iha_msgout_reject(sc, iot, ioh);
2000: break;
2001: }
2002:
2003: if (phase != PHASE_MSG_IN)
2004: return (phase);
2005: }
2006: /* NOTREACHED */
2007: }
2008:
2009: int
2010: iha_msgin_ignore_wid_resid(sc, iot, ioh)
2011: struct iha_softc *sc;
2012: bus_space_tag_t iot;
2013: bus_space_handle_t ioh;
2014: {
2015: int phase;
2016:
2017: phase = iha_wait(sc, iot, ioh, MSG_ACCEPT);
2018:
2019: if (phase == PHASE_MSG_IN) {
2020: phase = iha_wait(sc, iot, ioh, XF_FIFO_IN);
2021:
2022: if (phase != -1) {
2023: bus_space_write_1(iot, ioh, TUL_SFIFO, 0);
2024: bus_space_read_1 (iot, ioh, TUL_SFIFO);
2025: bus_space_read_1 (iot, ioh, TUL_SFIFO);
2026:
2027: phase = iha_wait(sc, iot, ioh, MSG_ACCEPT);
2028: }
2029: }
2030:
2031: return (phase);
2032: }
2033:
2034: int
2035: iha_msgin_extended(sc, iot, ioh)
2036: struct iha_softc *sc;
2037: bus_space_tag_t iot;
2038: bus_space_handle_t ioh;
2039: {
2040: u_int16_t flags;
2041: int i, phase, msglen, msgcode;
2042:
2043: /* XXX - can we just stop reading and reject, or do we have to
2044: * read all input, discarding the excess, and then reject
2045: */
2046: for (i = 0; i < IHA_MAX_EXTENDED_MSG; i++) {
2047: phase = iha_wait(sc, iot, ioh, MSG_ACCEPT);
2048:
2049: if (phase != PHASE_MSG_IN)
2050: return (phase);
2051:
2052: bus_space_write_4(iot, ioh, TUL_STCNT0, 1);
2053:
2054: if (iha_wait(sc, iot, ioh, XF_FIFO_IN) == -1)
2055: return (-1);
2056:
2057: sc->HCS_Msg[i] = bus_space_read_1(iot, ioh, TUL_SFIFO);
2058:
2059: if (sc->HCS_Msg[0] == i)
2060: break;
2061: }
2062:
2063: msglen = sc->HCS_Msg[0];
2064: msgcode = sc->HCS_Msg[1];
2065:
2066: if ((msglen == MSG_EXT_SDTR_LEN) && (msgcode == MSG_EXT_SDTR)) {
2067: if (iha_msgin_sdtr(sc) == 0) {
2068: iha_sync_done(sc, iot, ioh);
2069: return (iha_wait(sc, iot, ioh, MSG_ACCEPT));
2070: }
2071:
2072: iha_set_ssig(iot, ioh, REQ | BSY | SEL, ATN);
2073:
2074: phase = iha_wait(sc, iot, ioh, MSG_ACCEPT);
2075: if (phase != PHASE_MSG_OUT)
2076: return (phase);
2077:
2078: /* Clear FIFO for important message - final SYNC offer */
2079: bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
2080:
2081: iha_sync_done(sc, iot, ioh); /* This is our final offer */
2082:
2083: } else if ((msglen == MSG_EXT_WDTR_LEN) && (msgcode == MSG_EXT_WDTR)) {
2084:
2085: flags = sc->HCS_ActScb->SCB_Tcs->TCS_Flags;
2086:
2087: if ((flags & FLAG_NO_WIDE) != 0)
2088: /* Offer 8 bit xfers only */
2089: sc->HCS_Msg[2] = MSG_EXT_WDTR_BUS_8_BIT;
2090:
2091: else if (sc->HCS_Msg[2] > MSG_EXT_WDTR_BUS_32_BIT)
2092: return (iha_msgout_reject(sc, iot, ioh));
2093:
2094: else if (sc->HCS_Msg[2] == MSG_EXT_WDTR_BUS_32_BIT)
2095: /* Offer 16 instead */
2096: sc->HCS_Msg[2] = MSG_EXT_WDTR_BUS_32_BIT;
2097:
2098: else {
2099: iha_wide_done(sc, iot, ioh);
2100: if ((flags & FLAG_NO_NEG_SYNC) == 0)
2101: iha_set_ssig(iot, ioh, REQ | BSY | SEL, ATN);
2102: return (iha_wait(sc, iot, ioh, MSG_ACCEPT));
2103: }
2104:
2105: iha_set_ssig(iot, ioh, REQ | BSY | SEL, ATN);
2106:
2107: phase = iha_wait(sc, iot, ioh, MSG_ACCEPT);
2108: if (phase != PHASE_MSG_OUT)
2109: return (phase);
2110:
2111: } else
2112: return (iha_msgout_reject(sc, iot, ioh));
2113:
2114: /* Send message built in sc->HCS_Msg[] */
2115: return (iha_msgout_extended(sc, iot, ioh));
2116: }
2117:
2118: /*
2119: * iha_msgin_sdtr - check SDTR msg in HCS_Msg. If the offer is
2120: * acceptable leave HCS_Msg as is and return 0.
2121: * If the negotiation must continue, modify HCS_Msg
2122: * as needed and return 1. Else return 0.
2123: */
2124: int
2125: iha_msgin_sdtr(sc)
2126: struct iha_softc *sc;
2127: {
2128: u_int16_t flags;
2129: u_int8_t default_period;
2130: int newoffer;
2131:
2132: flags = sc->HCS_ActScb->SCB_Tcs->TCS_Flags;
2133:
2134: default_period = iha_rate_tbl[flags & FLAG_SCSI_RATE];
2135:
2136: if (sc->HCS_Msg[3] == 0) /* target offered async only. Accept it. */
2137: return (0);
2138:
2139: newoffer = 0;
2140:
2141: if ((flags & FLAG_NO_SYNC) != 0) {
2142: sc->HCS_Msg[3] = 0;
2143: newoffer = 1;
2144: }
2145:
2146: if (sc->HCS_Msg[3] > IHA_MAX_TARGETS-1) {
2147: sc->HCS_Msg[3] = IHA_MAX_TARGETS-1;
2148: newoffer = 1;
2149: }
2150:
2151: if (sc->HCS_Msg[2] < default_period) {
2152: sc->HCS_Msg[2] = default_period;
2153: newoffer = 1;
2154: }
2155:
2156: if (sc->HCS_Msg[2] >= 59) {
2157: sc->HCS_Msg[3] = 0;
2158: newoffer = 1;
2159: }
2160:
2161: return (newoffer);
2162: }
2163:
2164: int
2165: iha_msgout(sc, iot, ioh, msg)
2166: struct iha_softc *sc;
2167: bus_space_tag_t iot;
2168: bus_space_handle_t ioh;
2169: u_int8_t msg;
2170: {
2171: bus_space_write_1(iot, ioh, TUL_SFIFO, msg);
2172:
2173: return (iha_wait(sc, iot, ioh, XF_FIFO_OUT));
2174: }
2175:
2176: void
2177: iha_msgout_abort(sc, iot, ioh, aborttype)
2178: struct iha_softc *sc;
2179: bus_space_tag_t iot;
2180: bus_space_handle_t ioh;
2181: u_int8_t aborttype;
2182: {
2183: iha_set_ssig(iot, ioh, REQ | BSY | SEL, ATN);
2184:
2185: switch (iha_wait(sc, iot, ioh, MSG_ACCEPT)) {
2186: case -1:
2187: break;
2188:
2189: case PHASE_MSG_OUT:
2190: sc->HCS_Flags |= FLAG_EXPECT_DISC;
2191: if (iha_msgout(sc, iot, ioh, aborttype) != -1)
2192: iha_bad_seq(sc);
2193: break;
2194:
2195: default:
2196: iha_bad_seq(sc);
2197: break;
2198: }
2199: }
2200:
2201: int
2202: iha_msgout_reject(sc, iot, ioh)
2203: struct iha_softc *sc;
2204: bus_space_tag_t iot;
2205: bus_space_handle_t ioh;
2206: {
2207: iha_set_ssig(iot, ioh, REQ | BSY | SEL, ATN);
2208:
2209: if (iha_wait(sc, iot, ioh, MSG_ACCEPT) == PHASE_MSG_OUT)
2210: return (iha_msgout(sc, iot, ioh, MSG_MESSAGE_REJECT));
2211:
2212: return (-1);
2213: }
2214:
2215: int
2216: iha_msgout_extended(sc, iot, ioh)
2217: struct iha_softc *sc;
2218: bus_space_tag_t iot;
2219: bus_space_handle_t ioh;
2220: {
2221: int phase;
2222:
2223: bus_space_write_1(iot, ioh, TUL_SFIFO, MSG_EXTENDED);
2224:
2225: bus_space_write_multi_1(iot, ioh, TUL_SFIFO,
2226: sc->HCS_Msg, sc->HCS_Msg[0]+1);
2227:
2228: phase = iha_wait(sc, iot, ioh, XF_FIFO_OUT);
2229:
2230: bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
2231: iha_set_ssig(iot, ioh, REQ | BSY | SEL | ATN, 0);
2232:
2233: return (phase);
2234: }
2235:
2236: int
2237: iha_msgout_wdtr(sc, iot, ioh)
2238: struct iha_softc *sc;
2239: bus_space_tag_t iot;
2240: bus_space_handle_t ioh;
2241: {
2242: sc->HCS_ActScb->SCB_Tcs->TCS_Flags |= FLAG_WIDE_DONE;
2243:
2244: sc->HCS_Msg[0] = MSG_EXT_WDTR_LEN;
2245: sc->HCS_Msg[1] = MSG_EXT_WDTR;
2246: sc->HCS_Msg[2] = MSG_EXT_WDTR_BUS_16_BIT;
2247:
2248: return (iha_msgout_extended(sc, iot, ioh));
2249: }
2250:
2251: int
2252: iha_msgout_sdtr(sc, iot, ioh)
2253: struct iha_softc *sc;
2254: bus_space_tag_t iot;
2255: bus_space_handle_t ioh;
2256: {
2257: u_int16_t rateindex;
2258: u_int8_t sync_rate;
2259:
2260: rateindex = sc->HCS_ActScb->SCB_Tcs->TCS_Flags & FLAG_SCSI_RATE;
2261:
2262: sync_rate = iha_rate_tbl[rateindex];
2263:
2264: sc->HCS_Msg[0] = MSG_EXT_SDTR_LEN;
2265: sc->HCS_Msg[1] = MSG_EXT_SDTR;
2266: sc->HCS_Msg[2] = sync_rate;
2267: sc->HCS_Msg[3] = IHA_MAX_TARGETS-1; /* REQ/ACK */
2268:
2269: return (iha_msgout_extended(sc, iot, ioh));
2270: }
2271:
2272: void
2273: iha_wide_done(sc, iot, ioh)
2274: struct iha_softc *sc;
2275: bus_space_tag_t iot;
2276: bus_space_handle_t ioh;
2277: {
2278: struct tcs *pTcs = sc->HCS_ActScb->SCB_Tcs;
2279:
2280: pTcs->TCS_JS_Period = 0;
2281:
2282: if (sc->HCS_Msg[2] != 0)
2283: pTcs->TCS_JS_Period |= PERIOD_WIDE_SCSI;
2284:
2285: pTcs->TCS_SConfig0 &= ~ALTPD;
2286: pTcs->TCS_Flags &= ~FLAG_SYNC_DONE;
2287: pTcs->TCS_Flags |= FLAG_WIDE_DONE;
2288:
2289: bus_space_write_1(iot, ioh, TUL_SCONFIG0, pTcs->TCS_SConfig0);
2290: bus_space_write_1(iot, ioh, TUL_SYNCM, pTcs->TCS_JS_Period);
2291: }
2292:
2293: void
2294: iha_sync_done(sc, iot, ioh)
2295: struct iha_softc *sc;
2296: bus_space_tag_t iot;
2297: bus_space_handle_t ioh;
2298: {
2299: struct tcs *pTcs = sc->HCS_ActScb->SCB_Tcs;
2300: int i;
2301:
2302: if ((pTcs->TCS_Flags & FLAG_SYNC_DONE) == 0) {
2303: if (sc->HCS_Msg[3] != 0) {
2304: pTcs->TCS_JS_Period |= sc->HCS_Msg[3];
2305:
2306: /* pick the highest possible rate */
2307: for (i = 0; i < sizeof(iha_rate_tbl); i++)
2308: if (iha_rate_tbl[i] >= sc->HCS_Msg[2])
2309: break;
2310:
2311: pTcs->TCS_JS_Period |= (i << 4);
2312: pTcs->TCS_SConfig0 |= ALTPD;
2313: }
2314:
2315: pTcs->TCS_Flags |= FLAG_SYNC_DONE;
2316:
2317: bus_space_write_1(iot, ioh, TUL_SCONFIG0, pTcs->TCS_SConfig0);
2318: bus_space_write_1(iot, ioh, TUL_SYNCM, pTcs->TCS_JS_Period);
2319: }
2320: }
2321:
2322: void
2323: iha_reset_chip(sc, iot, ioh)
2324: struct iha_softc *sc;
2325: bus_space_tag_t iot;
2326: bus_space_handle_t ioh;
2327: {
2328: int i;
2329:
2330: /* reset tulip chip */
2331:
2332: bus_space_write_1(iot, ioh, TUL_SCTRL0, RSCSI);
2333:
2334: do
2335: sc->HCS_JSInt = bus_space_read_1(iot, ioh, TUL_SISTAT);
2336: while((sc->HCS_JSInt & SRSTD) == 0);
2337:
2338: iha_set_ssig(iot, ioh, 0, 0);
2339:
2340: /*
2341: * Stall for 2 seconds, wait for target's firmware ready.
2342: */
2343: for (i = 0; i < 2000; i++)
2344: DELAY (1000);
2345:
2346: bus_space_read_1(iot, ioh, TUL_SISTAT); /* Clear any active interrupt*/
2347: }
2348:
2349: void
2350: iha_select(sc, iot, ioh, pScb, select_type)
2351: struct iha_softc *sc;
2352: bus_space_tag_t iot;
2353: bus_space_handle_t ioh;
2354: struct iha_scb *pScb;
2355: u_int8_t select_type;
2356: {
2357: int s;
2358:
2359: switch (select_type) {
2360: case SEL_ATN:
2361: bus_space_write_1(iot, ioh, TUL_SFIFO, pScb->SCB_Ident);
2362: bus_space_write_multi_1(iot, ioh, TUL_SFIFO,
2363: pScb->SCB_CDB, pScb->SCB_CDBLen);
2364:
2365: pScb->SCB_NxtStat = 2;
2366: break;
2367:
2368: case SELATNSTOP:
2369: pScb->SCB_NxtStat = 1;
2370: break;
2371:
2372: case SEL_ATN3:
2373: bus_space_write_1(iot, ioh, TUL_SFIFO, pScb->SCB_Ident);
2374: bus_space_write_1(iot, ioh, TUL_SFIFO, pScb->SCB_TagMsg);
2375: bus_space_write_1(iot, ioh, TUL_SFIFO, pScb->SCB_TagId);
2376:
2377: bus_space_write_multi_1(iot, ioh, TUL_SFIFO, pScb->SCB_CDB,
2378: pScb->SCB_CDBLen);
2379:
2380: pScb->SCB_NxtStat = 2;
2381: break;
2382:
2383: default:
2384: #ifdef IHA_DEBUG_STATE
2385: sc_print_addr(pScb->SCB_Xs->sc_link);
2386: printf("[debug] iha_select() - unknown select type = 0x%02x\n",
2387: select_type);
2388: #endif
2389: return;
2390: }
2391:
2392: s = splbio();
2393: TAILQ_REMOVE(&sc->HCS_PendScb, pScb, SCB_ScbList);
2394: splx(s);
2395:
2396: pScb->SCB_Status = STATUS_SELECT;
2397:
2398: sc->HCS_ActScb = pScb;
2399:
2400: bus_space_write_1(iot, ioh, TUL_SCMD, select_type);
2401: }
2402:
2403: /*
2404: * iha_wait - wait for an interrupt to service or a SCSI bus phase change
2405: * after writing the supplied command to the tulip chip. If
2406: * the command is NO_OP, skip the command writing.
2407: */
2408: int
2409: iha_wait(sc, iot, ioh, cmd)
2410: struct iha_softc *sc;
2411: bus_space_tag_t iot;
2412: bus_space_handle_t ioh;
2413: u_int8_t cmd;
2414: {
2415: if (cmd != NO_OP)
2416: bus_space_write_1(iot, ioh, TUL_SCMD, cmd);
2417:
2418: /*
2419: * Have to do this here, in addition to in iha_isr, because
2420: * interrupts might be turned off when we get here.
2421: */
2422: do
2423: sc->HCS_JSStatus0 = bus_space_read_1(iot, ioh, TUL_STAT0);
2424: while ((sc->HCS_JSStatus0 & INTPD) == 0);
2425:
2426: sc->HCS_JSStatus1 = bus_space_read_1(iot, ioh, TUL_STAT1);
2427: sc->HCS_JSInt = bus_space_read_1(iot, ioh, TUL_SISTAT);
2428:
2429: sc->HCS_Phase = sc->HCS_JSStatus0 & PH_MASK;
2430:
2431: if ((sc->HCS_JSInt & SRSTD) != 0) {
2432: /* SCSI bus reset interrupt */
2433: iha_reset_scsi_bus(sc);
2434: return (-1);
2435: }
2436:
2437: if ((sc->HCS_JSInt & RSELED) != 0)
2438: /* Reselection interrupt */
2439: return (iha_resel(sc, iot, ioh));
2440:
2441: if ((sc->HCS_JSInt & STIMEO) != 0) {
2442: /* selected/reselected timeout interrupt */
2443: iha_busfree(sc, iot, ioh);
2444: return (-1);
2445: }
2446:
2447: if ((sc->HCS_JSInt & DISCD) != 0) {
2448: /* BUS disconnection interrupt */
2449: if ((sc->HCS_Flags & FLAG_EXPECT_DONE_DISC) != 0) {
2450: bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
2451: bus_space_write_1(iot, ioh, TUL_SCONFIG0,
2452: SCONFIG0DEFAULT);
2453: bus_space_write_1(iot, ioh, TUL_SCTRL1, EHRSL);
2454: iha_append_done_scb(sc, sc->HCS_ActScb, HOST_OK);
2455: sc->HCS_Flags &= ~FLAG_EXPECT_DONE_DISC;
2456:
2457: } else if ((sc->HCS_Flags & FLAG_EXPECT_DISC) != 0) {
2458: bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO);
2459: bus_space_write_1(iot, ioh, TUL_SCONFIG0,
2460: SCONFIG0DEFAULT);
2461: bus_space_write_1(iot, ioh, TUL_SCTRL1, EHRSL);
2462: sc->HCS_ActScb = NULL;
2463: sc->HCS_Flags &= ~FLAG_EXPECT_DISC;
2464:
2465: } else
2466: iha_busfree(sc, iot, ioh);
2467:
2468: return (-1);
2469: }
2470:
2471: return (sc->HCS_Phase);
2472: }
2473:
2474: /*
2475: * iha_done_scb - We have a scb which has been processed by the
2476: * adaptor, now we look to see how the operation went.
2477: */
2478: void
2479: iha_done_scb(sc, pScb)
2480: struct iha_softc *sc;
2481: struct iha_scb *pScb;
2482: {
2483: struct scsi_sense_data *s1, *s2;
2484: struct scsi_xfer *xs = pScb->SCB_Xs;
2485:
2486: if (xs != NULL) {
2487: timeout_del(&xs->stimeout);
2488:
2489: xs->status = pScb->SCB_TaStat;
2490:
2491: if ((pScb->SCB_Flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) != 0) {
2492: bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma,
2493: 0, pScb->SCB_BufChars,
2494: ((pScb->SCB_Flags & SCSI_DATA_IN) ?
2495: BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
2496: bus_dmamap_unload(sc->sc_dmat, pScb->SCB_DataDma);
2497: }
2498: if ((pScb->SCB_Flags & FLAG_SG) != 0) {
2499: bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma,
2500: 0, sizeof(pScb->SCB_SGList),
2501: BUS_DMASYNC_POSTWRITE);
2502: bus_dmamap_unload(sc->sc_dmat, pScb->SCB_SGDma);
2503: }
2504:
2505: switch (pScb->SCB_HaStat) {
2506: case HOST_OK:
2507: switch (pScb->SCB_TaStat) {
2508: case SCSI_OK:
2509: case SCSI_COND_MET:
2510: case SCSI_INTERM:
2511: case SCSI_INTERM_COND_MET:
2512: xs->resid = pScb->SCB_BufCharsLeft;
2513: xs->error = XS_NOERROR;
2514: break;
2515:
2516: case SCSI_RESV_CONFLICT:
2517: case SCSI_BUSY:
2518: case SCSI_QUEUE_FULL:
2519: xs->error = XS_BUSY;
2520: break;
2521:
2522: case SCSI_TERMINATED:
2523: case SCSI_ACA_ACTIVE:
2524: case SCSI_CHECK:
2525: s1 = &pScb->SCB_ScsiSenseData;
2526: s2 = &xs->sense;
2527: *s2 = *s1;
2528:
2529: xs->error = XS_SENSE;
2530: break;
2531:
2532: default:
2533: xs->error = XS_DRIVER_STUFFUP;
2534: break;
2535: }
2536: break;
2537:
2538: case HOST_SEL_TOUT:
2539: xs->error = XS_SELTIMEOUT;
2540: break;
2541:
2542: case HOST_SCSI_RST:
2543: case HOST_DEV_RST:
2544: xs->error = XS_RESET;
2545: break;
2546:
2547: case HOST_SPERR:
2548: sc_print_addr(xs->sc_link);
2549: printf("SCSI Parity error detected\n");
2550: xs->error = XS_DRIVER_STUFFUP;
2551: break;
2552:
2553: case HOST_TIMED_OUT:
2554: xs->error = XS_TIMEOUT;
2555: break;
2556:
2557: case HOST_DO_DU:
2558: case HOST_BAD_PHAS:
2559: default:
2560: xs->error = XS_DRIVER_STUFFUP;
2561: break;
2562: }
2563:
2564: xs->flags |= ITSDONE;
2565: scsi_done(xs);
2566: }
2567:
2568: iha_append_free_scb(sc, pScb);
2569: }
2570:
2571: void
2572: iha_timeout(arg)
2573: void *arg;
2574: {
2575: struct iha_scb *pScb = (struct iha_scb *)arg;
2576: struct scsi_xfer *xs = pScb->SCB_Xs;
2577:
2578: if (xs != NULL) {
2579: sc_print_addr(xs->sc_link);
2580: printf("SCSI OpCode 0x%02x timed out\n", xs->cmd->opcode);
2581: iha_abort_xs(xs->sc_link->adapter_softc, xs, HOST_TIMED_OUT);
2582: }
2583: }
2584:
2585: void
2586: iha_exec_scb(sc, pScb)
2587: struct iha_softc *sc;
2588: struct iha_scb *pScb;
2589: {
2590: bus_space_handle_t ioh;
2591: bus_space_tag_t iot;
2592: int s;
2593:
2594: s = splbio();
2595:
2596: if (((pScb->SCB_Flags & SCSI_RESET) != 0)
2597: || (pScb->SCB_CDB[0] == REQUEST_SENSE))
2598: iha_push_pend_scb(sc, pScb); /* Insert SCB at head of Pend */
2599: else
2600: iha_append_pend_scb(sc, pScb); /* Append SCB to tail of Pend */
2601:
2602: /*
2603: * Run through iha_main() to ensure something is active, if
2604: * only this new SCB.
2605: */
2606: if (sc->HCS_Semaph != SEMAPH_IN_MAIN) {
2607: iot = sc->sc_iot;
2608: ioh = sc->sc_ioh;
2609:
2610: bus_space_write_1(iot, ioh, TUL_IMSK, MASK_ALL);
2611: sc->HCS_Semaph = SEMAPH_IN_MAIN;
2612:
2613: splx(s);
2614: iha_main(sc, iot, ioh);
2615: s = splbio();
2616:
2617: sc->HCS_Semaph = ~SEMAPH_IN_MAIN;
2618: bus_space_write_1(iot, ioh, TUL_IMSK, (MASK_ALL & ~MSCMP));
2619: }
2620:
2621: splx(s);
2622: }
2623:
2624:
2625: /*
2626: * iha_set_ssig - read the current scsi signal mask, then write a new
2627: * one which turns off/on the specified signals.
2628: */
2629: void
2630: iha_set_ssig( iot, ioh, offsigs, onsigs)
2631: bus_space_tag_t iot;
2632: bus_space_handle_t ioh;
2633: u_int8_t offsigs, onsigs;
2634: {
2635: u_int8_t currsigs;
2636:
2637: currsigs = bus_space_read_1(iot, ioh, TUL_SSIGI);
2638: bus_space_write_1(iot, ioh, TUL_SSIGO, (currsigs & ~offsigs) | onsigs);
2639: }
2640:
2641: void
2642: iha_print_info(sc, target)
2643: struct iha_softc *sc;
2644: int target;
2645: {
2646: u_int8_t period = sc->HCS_Tcs[target].TCS_JS_Period;
2647: u_int8_t config = sc->HCS_Tcs[target].TCS_SConfig0;
2648: int rate;
2649:
2650: printf("%s: target %d using %d bit ", sc->sc_dev.dv_xname, target,
2651: (period & PERIOD_WIDE_SCSI) ? 16 : 8);
2652:
2653: if ((period & PERIOD_SYOFS) == 0)
2654: printf("async ");
2655: else {
2656: rate = (period & PERIOD_SYXPD) >> 4;
2657: if ((config & ALTPD) == 0)
2658: rate = 100 + rate * 50;
2659: else
2660: rate = 50 + rate * 25;
2661: rate = 1000000000 / rate;
2662: printf("%d.%d MHz %d REQ/ACK offset ", rate / 1000000,
2663: (rate % 1000000 + 99999) / 100000, period & PERIOD_SYOFS);
2664: }
2665:
2666: printf("xfers\n");
2667: }
2668:
2669:
2670: /*
2671: * iha_alloc_scbs - allocate and map the SCB's for the supplied iha_softc
2672: */
2673: int
2674: iha_alloc_scbs(sc)
2675: struct iha_softc *sc;
2676: {
2677: bus_dma_segment_t seg;
2678: int error, rseg;
2679:
2680: /*
2681: * Allocate dma-safe memory for the SCB's
2682: */
2683: if ((error = bus_dmamem_alloc(sc->sc_dmat,
2684: sizeof(struct iha_scb)*IHA_MAX_SCB,
2685: NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT))
2686: != 0) {
2687: printf("%s: unable to allocate SCBs,"
2688: " error = %d\n", sc->sc_dev.dv_xname, error);
2689: return (error);
2690: }
2691: if ((error = bus_dmamem_map(sc->sc_dmat,
2692: &seg, rseg, sizeof(struct iha_scb)*IHA_MAX_SCB,
2693: (caddr_t *)&sc->HCS_Scb, BUS_DMA_NOWAIT | BUS_DMA_COHERENT))
2694: != 0) {
2695: printf("%s: unable to map SCBs, error = %d\n",
2696: sc->sc_dev.dv_xname, error);
2697: return (error);
2698: }
2699: bzero(sc->HCS_Scb, sizeof(struct iha_scb)*IHA_MAX_SCB);
2700:
2701: return (0);
2702: }
2703:
2704: /*
2705: * iha_read_eeprom - read contents of serial EEPROM into iha_nvram pointed at
2706: * by parameter nvram.
2707: */
2708: void
2709: iha_read_eeprom(iot, ioh, nvram)
2710: bus_space_tag_t iot;
2711: bus_space_handle_t ioh;
2712: struct iha_nvram *nvram;
2713: {
2714: u_int32_t chksum;
2715: u_int16_t *np;
2716: u_int8_t gctrl, addr;
2717:
2718: const int chksum_addr = offsetof(struct iha_nvram, NVM_CheckSum) / 2;
2719:
2720: /* Enable EEProm programming */
2721: gctrl = bus_space_read_1(iot, ioh, TUL_GCTRL0) | EEPRG;
2722: bus_space_write_1(iot, ioh, TUL_GCTRL0, gctrl);
2723:
2724: /* Read EEProm */
2725: np = (u_int16_t *)nvram;
2726: for (addr=0, chksum=0; addr < chksum_addr; addr++, np++) {
2727: *np = iha_se2_rd(iot, ioh, addr);
2728: chksum += *np;
2729: }
2730:
2731: chksum &= 0x0000ffff;
2732: nvram->NVM_CheckSum = iha_se2_rd(iot, ioh, chksum_addr);
2733:
2734: /* Disable EEProm programming */
2735: gctrl = bus_space_read_1(iot, ioh, TUL_GCTRL0) & ~EEPRG;
2736: bus_space_write_1(iot, ioh, TUL_GCTRL0, gctrl);
2737:
2738: if ((nvram->NVM_Signature != SIGNATURE)
2739: ||
2740: (nvram->NVM_CheckSum != chksum))
2741: panic("iha: invalid EEPROM, bad signature or checksum");
2742: }
2743:
2744: /*
2745: * iha_se2_rd - read & return the 16 bit value at the specified
2746: * offset in the Serial E2PROM
2747: *
2748: */
2749: u_int16_t
2750: iha_se2_rd(iot, ioh, addr)
2751: bus_space_tag_t iot;
2752: bus_space_handle_t ioh;
2753: u_int8_t addr;
2754: {
2755: u_int16_t readWord;
2756: u_int8_t bit;
2757: int i;
2758:
2759: /* Send 'READ' instruction == address | READ bit */
2760: iha_se2_instr(iot, ioh, (addr | NVREAD));
2761:
2762: readWord = 0;
2763: for (i = 15; i >= 0; i--) {
2764: bus_space_write_1(iot, ioh, TUL_NVRAM, NVRCS | NVRCK);
2765: DELAY(5);
2766:
2767: bus_space_write_1(iot, ioh, TUL_NVRAM, NVRCS);
2768: DELAY(5);
2769:
2770: /* sample data after the following edge of clock */
2771: bit = bus_space_read_1(iot, ioh, TUL_NVRAM) & NVRDI;
2772: DELAY(5);
2773:
2774: readWord += bit << i;
2775: }
2776:
2777: bus_space_write_1(iot, ioh, TUL_NVRAM, 0);
2778: DELAY(5);
2779:
2780: return (readWord);
2781: }
2782:
2783: /*
2784: * iha_se2_instr - write an octet to serial E2PROM one bit at a time
2785: */
2786: void
2787: iha_se2_instr(iot, ioh, instr)
2788: bus_space_tag_t iot;
2789: bus_space_handle_t ioh;
2790: u_int8_t instr;
2791: {
2792: u_int8_t b;
2793: int i;
2794:
2795: b = NVRCS | NVRDO; /* Write the start bit (== 1) */
2796:
2797: bus_space_write_1(iot, ioh, TUL_NVRAM, b);
2798: DELAY(5);
2799: bus_space_write_1(iot, ioh, TUL_NVRAM, b | NVRCK);
2800: DELAY(5);
2801:
2802: for (i = 0; i < 8; i++, instr <<= 1) {
2803: if (instr & 0x80)
2804: b = NVRCS | NVRDO; /* Write a 1 bit */
2805: else
2806: b = NVRCS; /* Write a 0 bit */
2807:
2808: bus_space_write_1(iot, ioh, TUL_NVRAM, b);
2809: DELAY(5);
2810: bus_space_write_1(iot, ioh, TUL_NVRAM, b | NVRCK);
2811: DELAY(5);
2812: }
2813:
2814: bus_space_write_1(iot, ioh, TUL_NVRAM, NVRCS);
2815: DELAY(5);
2816:
2817: return;
2818: }
2819:
2820: /*
2821: * iha_reset_tcs - reset the target control structure pointed
2822: * to by pTcs to default values. TCS_Flags
2823: * only has the negotiation done bits reset as
2824: * the other bits are fixed at initialization.
2825: */
2826: void
2827: iha_reset_tcs(pTcs, config0)
2828: struct tcs *pTcs;
2829: u_int8_t config0;
2830: {
2831: pTcs->TCS_Flags &= ~(FLAG_SYNC_DONE | FLAG_WIDE_DONE);
2832: pTcs->TCS_JS_Period = 0;
2833: pTcs->TCS_SConfig0 = config0;
2834: pTcs->TCS_TagCnt = 0;
2835: pTcs->TCS_NonTagScb = NULL;
2836: }
CVSweb