Annotation of sys/dev/ic/trm.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: trm.c,v 1.7 2005/12/03 16:53:16 krw Exp $
2: * ------------------------------------------------------------
3: * O.S : OpenBSD
4: * File Name : trm.c
5: * Device Driver for Tekram DC395U/UW/F,DC315/U
6: * PCI SCSI Bus Master Host Adapter
7: * (SCSI chip set used Tekram ASIC TRM-S1040)
8: *
9: * (C)Copyright 1995-1999 Tekram Technology Co., Ltd.
10: * (C)Copyright 2001-2002 Ashley R. Martens and Kenneth R Westerback
11: * ------------------------------------------------------------
12: * HISTORY:
13: *
14: * REV# DATE NAME DESCRIPTION
15: * 1.00 05/01/99 ERICH CHEN First released for NetBSD 1.4.x
16: * 1.01 00/00/00 MARTIN AKESSON Port to OpenBSD 2.8
17: * 1.02 09/19/01 ASHLEY MARTENS Cleanup and formatting
18: * 2.00 01/00/02 KENNETH R WESTERBACK Rewrite of the bus and code logic
19: * ------------------------------------------------------------
20: *
21: * Redistribution and use in source and binary forms, with or without
22: * modification, are permitted provided that the following conditions
23: * are met:
24: * 1. Redistributions of source code must retain the above copyright
25: * notice, this list of conditions and the following disclaimer.
26: * 2. Redistributions in binary form must reproduce the above copyright
27: * notice, this list of conditions and the following disclaimer in the
28: * documentation and/or other materials provided with the distribution.
29: * 3. The name of the author may not be used to endorse or promote products
30: * derived from this software without specific prior written permission.
31: *
32: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
33: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
34: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
35: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
36: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
37: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
41: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42: *
43: * ------------------------------------------------------------
44: */
45:
46: #include <sys/param.h>
47: #include <sys/systm.h>
48: #include <sys/kernel.h>
49: #include <sys/malloc.h>
50: #include <sys/buf.h>
51: #include <sys/device.h>
52:
53: #include <machine/bus.h>
54:
55: #include <scsi/scsi_all.h>
56: #include <scsi/scsiconf.h>
57: #include <scsi/scsi_message.h>
58:
59: #include <dev/pci/pcidevs.h>
60: #include <dev/ic/trm.h>
61:
62: /* #define TRM_DEBUG0 */
63:
64: void trm_minphys(struct buf *);
65:
66: void trm_initSRB(struct trm_scsi_req_q *);
67:
68: void trm_check_eeprom(struct trm_adapter_nvram *, bus_space_tag_t, bus_space_handle_t);
69: void trm_read_all (struct trm_adapter_nvram *, bus_space_tag_t, bus_space_handle_t);
70: void trm_write_all (struct trm_adapter_nvram *, bus_space_tag_t, bus_space_handle_t);
71:
72: void trm_set_data (bus_space_tag_t, bus_space_handle_t, u_int8_t, u_int8_t);
73: void trm_write_cmd(bus_space_tag_t, bus_space_handle_t, u_int8_t, u_int8_t);
74:
75: u_int8_t trm_get_data(bus_space_tag_t, bus_space_handle_t, u_int8_t);
76:
77: void trm_wait_30us(bus_space_tag_t, bus_space_handle_t);
78:
79: int trm_scsi_cmd(struct scsi_xfer *);
80:
81: struct trm_scsi_req_q *trm_GetFreeSRB(struct trm_softc *);
82:
83: void trm_DataOutPhase0(struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
84: void trm_DataInPhase0 (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
85: void trm_StatusPhase0 (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
86: void trm_MsgOutPhase0 (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
87: void trm_MsgInPhase0 (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
88: void trm_DataOutPhase1(struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
89: void trm_DataInPhase1 (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
90: void trm_CommandPhase1(struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
91: void trm_StatusPhase1 (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
92: void trm_MsgOutPhase1 (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
93: void trm_MsgInPhase1 (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
94: void trm_Nop (struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
95:
96: void trm_SetXferParams (struct trm_softc *, struct trm_dcb *, int);
97:
98: void trm_DataIO_transfer(struct trm_softc *, struct trm_scsi_req_q *, u_int16_t);
99:
100: int trm_StartSRB (struct trm_softc *, struct trm_scsi_req_q *);
101: void trm_ReleaseSRB (struct trm_softc *, struct trm_scsi_req_q *);
102: void trm_RewaitSRB (struct trm_softc *, struct trm_scsi_req_q *);
103: void trm_FinishSRB (struct trm_softc *, struct trm_scsi_req_q *);
104: void trm_RequestSense(struct trm_softc *, struct trm_scsi_req_q *);
105:
106: void trm_initAdapter (struct trm_softc *);
107: void trm_Disconnect (struct trm_softc *);
108: void trm_Reselect (struct trm_softc *);
109: void trm_GoingSRB_Done (struct trm_softc *);
110: void trm_ScsiRstDetect (struct trm_softc *);
111: void trm_ResetSCSIBus (struct trm_softc *);
112: void trm_reset (struct trm_softc *);
113: void trm_StartWaitingSRB (struct trm_softc *);
114: void trm_ResetAllDevParam(struct trm_softc *);
115: void trm_RecoverSRB (struct trm_softc *);
116: void trm_linkSRB (struct trm_softc *);
117:
118: void trm_initACB(struct trm_softc *, int);
119:
120: void trm_ResetDevParam(struct trm_softc *, struct trm_dcb *, u_int8_t);
121:
122: void trm_EnableMsgOut(struct trm_softc *, u_int8_t);
123:
124: void trm_timeout(void *);
125:
126: void trm_print_info(struct trm_softc *, struct trm_dcb *);
127:
128: /*
129: * Define structures
130: */
131: struct cfdriver trm_cd = {
132: NULL, "trm", DV_DULL
133: };
134:
135: struct scsi_adapter trm_switch = {
136: trm_scsi_cmd,
137: trm_minphys,
138: NULL,
139: NULL
140: };
141:
142: static struct scsi_device trm_device = {
143: NULL, /* Use default error handler */
144: NULL, /* have a queue, served by this */
145: NULL, /* have no async handler */
146: NULL, /* Use default 'done' routine */
147: };
148:
149: /*
150: * ------------------------------------------------------------
151: *
152: * stateV = (void *) trm_SCSI_phase0[phase]
153: *
154: * ------------------------------------------------------------
155: */
156: static void *trm_SCSI_phase0[8] = {
157: trm_DataOutPhase0, /* phase:0 */
158: trm_DataInPhase0, /* phase:1 */
159: trm_Nop, /* phase:2 */
160: trm_StatusPhase0, /* phase:3 */
161: trm_Nop, /* phase:4 */
162: trm_Nop, /* phase:5 */
163: trm_MsgOutPhase0, /* phase:6 */
164: trm_MsgInPhase0, /* phase:7 */
165: };
166:
167: /*
168: * ------------------------------------------------------------
169: *
170: * stateV = (void *) trm_SCSI_phase1[phase]
171: *
172: * ------------------------------------------------------------
173: */
174: static void *trm_SCSI_phase1[8] = {
175: trm_DataOutPhase1, /* phase:0 */
176: trm_DataInPhase1, /* phase:1 */
177: trm_CommandPhase1, /* phase:2 */
178: trm_StatusPhase1, /* phase:3 */
179: trm_Nop, /* phase:4 */
180: trm_Nop, /* phase:5 */
181: trm_MsgOutPhase1, /* phase:6 */
182: trm_MsgInPhase1, /* phase:7 */
183: };
184:
185:
186: struct trm_adapter_nvram trm_eepromBuf[TRM_MAX_ADAPTER_NUM];
187: /*
188: *Fast20: 000 50ns, 20.0 Mbytes/s
189: * 001 75ns, 13.3 Mbytes/s
190: * 010 100ns, 10.0 Mbytes/s
191: * 011 125ns, 8.0 Mbytes/s
192: * 100 150ns, 6.6 Mbytes/s
193: * 101 175ns, 5.7 Mbytes/s
194: * 110 200ns, 5.0 Mbytes/s
195: * 111 250ns, 4.0 Mbytes/s
196: *
197: *Fast40: 000 25ns, 40.0 Mbytes/s
198: * 001 50ns, 20.0 Mbytes/s
199: * 010 75ns, 13.3 Mbytes/s
200: * 011 100ns, 10.0 Mbytes/s
201: * 100 125ns, 8.0 Mbytes/s
202: * 101 150ns, 6.6 Mbytes/s
203: * 110 175ns, 5.7 Mbytes/s
204: * 111 200ns, 5.0 Mbytes/s
205: */
206:
207: /*
208: * real period:
209: */
210: u_int8_t trm_clock_period[8] = {
211: /* nanosecond divided by 4 */
212: 12, /* 48 ns 20 MB/sec */
213: 18, /* 72 ns 13.3 MB/sec */
214: 25, /* 100 ns 10.0 MB/sec */
215: 31, /* 124 ns 8.0 MB/sec */
216: 37, /* 148 ns 6.6 MB/sec */
217: 43, /* 172 ns 5.7 MB/sec */
218: 50, /* 200 ns 5.0 MB/sec */
219: 62 /* 248 ns 4.0 MB/sec */
220: };
221:
222: /*
223: * ------------------------------------------------------------
224: * Function : trm_GetFreeSRB
225: * Purpose : Get the first free SRB
226: * Inputs :
227: * Return : NULL or a free SCSI Request block
228: * ------------------------------------------------------------
229: */
230: struct trm_scsi_req_q *
231: trm_GetFreeSRB(struct trm_softc *sc)
232: {
233: struct trm_scsi_req_q *pSRB;
234:
235: /* ASSUME we are called from inside a splbio()/splx() region */
236:
237: pSRB = TAILQ_FIRST(&sc->freeSRB);
238:
239: if (pSRB != NULL)
240: TAILQ_REMOVE(&sc->freeSRB, pSRB, link);
241:
242: #ifdef TRM_DEBUG0
243: printf("%s: trm_GetFreeSRB. pSRB = %p, next pSRB = %p\n",
244: sc->sc_device.dv_xname, pSRB, TAILQ_FIRST(&sc->freeSRB));
245: #endif
246:
247: return pSRB;
248: }
249:
250: /*
251: * ------------------------------------------------------------
252: * Function : trm_RewaitSRB
253: * Purpose : Q back to pending Q
254: * Inputs : struct trm_dcb * -
255: * struct trm_scsi_req_q * -
256: * ------------------------------------------------------------
257: */
258: void
259: trm_RewaitSRB(struct trm_softc *sc, struct trm_scsi_req_q *pSRB)
260: {
261: int intflag;
262:
263: intflag = splbio();
264:
265: if ((pSRB->SRBFlag & TRM_ON_WAITING_SRB) != 0) {
266: pSRB->SRBFlag &= ~TRM_ON_WAITING_SRB;
267: TAILQ_REMOVE(&sc->waitingSRB, pSRB, link);
268: }
269:
270: if ((pSRB->SRBFlag & TRM_ON_GOING_SRB) != 0) {
271: pSRB->SRBFlag &= ~TRM_ON_GOING_SRB;
272: TAILQ_REMOVE(&sc->goingSRB, pSRB, link);
273: }
274:
275: pSRB->SRBState = TRM_READY;
276: pSRB->TargetStatus = SCSI_OK;
277: pSRB->AdaptStatus = TRM_STATUS_GOOD;
278:
279: pSRB->SRBFlag |= TRM_ON_WAITING_SRB;
280: TAILQ_INSERT_HEAD(&sc->waitingSRB, pSRB, link);
281:
282: splx(intflag);
283: }
284:
285: /*
286: * ------------------------------------------------------------
287: * Function : trm_StartWaitingSRB
288: * Purpose : If there is no active DCB then run robin through
289: * the DCB's to find the next waiting SRB
290: * and move it to the going list.
291: * Inputs : struct trm_softc * -
292: * ------------------------------------------------------------
293: */
294: void
295: trm_StartWaitingSRB(struct trm_softc *sc)
296: {
297: struct trm_scsi_req_q *pSRB, *next;
298: int intflag;
299:
300: intflag = splbio();
301:
302: if ((sc->pActiveDCB != NULL) ||
303: (TAILQ_EMPTY(&sc->waitingSRB)) ||
304: (sc->sc_Flag & (RESET_DETECT | RESET_DONE | RESET_DEV)) != 0)
305: return;
306:
307: for (pSRB = TAILQ_FIRST(&sc->waitingSRB); pSRB != NULL; pSRB = next) {
308: next = TAILQ_NEXT(pSRB, link);
309: if (trm_StartSRB(sc, pSRB) == 0) {
310: pSRB->SRBFlag &= ~TRM_ON_WAITING_SRB;
311: TAILQ_REMOVE(&sc->waitingSRB, pSRB, link);
312: pSRB->SRBFlag |= TRM_ON_GOING_SRB;
313: TAILQ_INSERT_TAIL(&sc->goingSRB, pSRB, link);
314: break;
315: }
316: }
317:
318: splx(intflag);
319: }
320:
321: /*
322: * ------------------------------------------------------------
323: * Function : trm_scsi_cmd
324: * Purpose : enqueues a SCSI command
325: * Inputs :
326: * Call By : GENERIC SCSI driver
327: * ------------------------------------------------------------
328: */
329: int
330: trm_scsi_cmd(struct scsi_xfer *xs)
331: {
332: struct trm_scsi_req_q *pSRB;
333: bus_space_handle_t ioh;
334: struct trm_softc *sc;
335: bus_space_tag_t iot;
336: struct trm_dcb *pDCB;
337: u_int8_t target, lun;
338: int i, error, intflag, xferflags;
339:
340: target = xs->sc_link->target;
341: lun = xs->sc_link->lun;
342:
343: sc = (struct trm_softc *)xs->sc_link->adapter_softc;
344: ioh = sc->sc_iohandle;
345: iot = sc->sc_iotag;
346:
347: #ifdef TRM_DEBUG0
348: if ((xs->flags & SCSI_POLL) != 0)
349: printf("%s: trm_scsi_cmd. sc = %p, xs = %p, targ/lun = %d/%d opcode = 0x%02x\n",
350: sc->sc_device.dv_xname, sc, xs, target, lun, xs->cmd->opcode);
351: #endif
352:
353: if (target >= TRM_MAX_TARGETS) {
354: printf("%s: target=%d >= %d\n",
355: sc->sc_device.dv_xname, target, TRM_MAX_TARGETS);
356: xs->error = XS_DRIVER_STUFFUP;
357: return COMPLETE;
358: }
359: if (lun >= TRM_MAX_LUNS) {
360: printf("%s: lun=%d >= %d\n",
361: sc->sc_device.dv_xname, lun, TRM_MAX_LUNS);
362: xs->error = XS_DRIVER_STUFFUP;
363: return COMPLETE;
364: }
365:
366: pDCB = sc->pDCB[target][lun];
367: if (pDCB == NULL) {
368: /* Removed as a result of INQUIRY proving no device present */
369: xs->error = XS_DRIVER_STUFFUP;
370: return COMPLETE;
371: }
372:
373: xferflags = xs->flags;
374: if (xferflags & SCSI_RESET) {
375: #ifdef TRM_DEBUG0
376: printf("%s: trm_reset\n", sc->sc_device.dv_xname);
377: #endif
378: trm_reset(sc);
379: xs->error = XS_NOERROR;
380: return COMPLETE;
381: }
382:
383: if (xferflags & ITSDONE) {
384: #ifdef TRM_DEBUG0
385: printf("%s: Is it done?\n", sc->sc_device.dv_xname);
386: #endif
387: xs->flags &= ~ITSDONE;
388: }
389:
390: xs->error = XS_NOERROR;
391: xs->status = SCSI_OK;
392: xs->resid = 0;
393:
394: intflag = splbio();
395:
396: pSRB = trm_GetFreeSRB(sc);
397:
398: if (pSRB == NULL) {
399: splx(intflag);
400: return TRY_AGAIN_LATER;
401: }
402:
403: /*
404: * BuildSRB(pSRB,pDCB);
405: */
406: if (xs->datalen != 0) {
407: #ifdef TRM_DEBUG0
408: printf("%s: xs->datalen=%x\n", sc->sc_device.dv_xname,
409: (u_int32_t)xs->datalen);
410: printf("%s: sc->sc_dmatag=0x%x\n", sc->sc_device.dv_xname,
411: (u_int32_t)sc->sc_dmatag);
412: printf("%s: pSRB->dmamapxfer=0x%x\n", sc->sc_device.dv_xname,
413: (u_int32_t)pSRB->dmamapxfer);
414: printf("%s: xs->data=0x%x\n", sc->sc_device.dv_xname,
415: (u_int32_t)xs->data);
416: #endif
417: if ((error = bus_dmamap_load(sc->sc_dmatag, pSRB->dmamapxfer,
418: xs->data, xs->datalen, NULL,
419: (xferflags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT :
420: BUS_DMA_WAITOK)) != 0) {
421: printf("%s: DMA transfer map unable to load, error = %d\n"
422: , sc->sc_device.dv_xname, error);
423: xs->error = XS_DRIVER_STUFFUP;
424: /*
425: * free SRB
426: */
427: TAILQ_INSERT_HEAD(&sc->freeSRB, pSRB, link);
428: splx(intflag);
429: return COMPLETE;
430: }
431:
432: bus_dmamap_sync(sc->sc_dmatag, pSRB->dmamapxfer,
433: 0, pSRB->dmamapxfer->dm_mapsize,
434: (xferflags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
435:
436: /*
437: * Set up the scatter gather list
438: */
439: for (i = 0; i < pSRB->dmamapxfer->dm_nsegs; i++) {
440: pSRB->SegmentX[i].address = pSRB->dmamapxfer->dm_segs[i].ds_addr;
441: pSRB->SegmentX[i].length = pSRB->dmamapxfer->dm_segs[i].ds_len;
442: }
443: pSRB->SRBTotalXferLength = xs->datalen;
444: pSRB->SRBSGCount = pSRB->dmamapxfer->dm_nsegs;
445: }
446:
447: pSRB->pSRBDCB = pDCB;
448: pSRB->xs = xs;
449: pSRB->ScsiCmdLen = xs->cmdlen;
450:
451: memcpy(pSRB->CmdBlock, xs->cmd, xs->cmdlen);
452:
453: splx (intflag);
454:
455: timeout_set(&xs->stimeout, trm_timeout, pSRB);
456:
457: intflag = splbio();
458:
459: pSRB->SRBFlag |= TRM_ON_WAITING_SRB;
460: TAILQ_INSERT_TAIL(&sc->waitingSRB, pSRB, link);
461: trm_StartWaitingSRB(sc);
462:
463: if ((xferflags & SCSI_POLL) == 0) {
464: timeout_add(&xs->stimeout, (xs->timeout * hz) / 1000);
465: splx(intflag);
466: return SUCCESSFULLY_QUEUED;
467: }
468:
469: while ((--xs->timeout > 0) && ((xs->flags & ITSDONE) == 0)) {
470: trm_Interrupt(sc);
471: DELAY(1000);
472: }
473:
474: if (xs->timeout == 0)
475: trm_timeout(pSRB);
476:
477: splx(intflag);
478: return COMPLETE;
479: }
480:
481: /*
482: * ------------------------------------------------------------
483: * Function : trm_ResetAllDevParam
484: * Purpose :
485: * Inputs : struct trm_softc *
486: * ------------------------------------------------------------
487: */
488: void
489: trm_ResetAllDevParam(struct trm_softc *sc)
490: {
491: struct trm_adapter_nvram *pEEpromBuf;
492: int target, quirks;
493:
494: pEEpromBuf = &trm_eepromBuf[sc->sc_AdapterUnit];
495:
496: for (target = 0; target < TRM_MAX_TARGETS; target++) {
497: if (target == sc->sc_AdaptSCSIID)
498: continue;
499:
500: if ((sc->pDCB[target][0]->DCBFlag & TRM_QUIRKS_VALID) == 0)
501: quirks = SDEV_NOWIDE | SDEV_NOSYNC | SDEV_NOTAGS;
502: else
503: quirks = sc->pDCB[target][0]->sc_link->quirks;
504:
505: trm_ResetDevParam(sc, sc->pDCB[target][0], quirks);
506: }
507: }
508:
509: /*
510: * ------------------------------------------------------------
511: * Function : trm_ResetDevParam
512: * Purpose :
513: * Inputs :
514: * ------------------------------------------------------------
515: */
516: void
517: trm_ResetDevParam(struct trm_softc *sc, struct trm_dcb *pDCB, u_int8_t quirks)
518: {
519: struct trm_adapter_nvram *pEEpromBuf = &trm_eepromBuf[sc->sc_AdapterUnit];
520: u_int8_t PeriodIndex;
521: const int target = pDCB->target;
522:
523: pDCB->DCBFlag &= TRM_QUIRKS_VALID;
524: pDCB->DCBFlag |= (TRM_WIDE_NEGO_ENABLE | TRM_SYNC_NEGO_ENABLE);
525:
526: pDCB->SyncPeriod = 0;
527: pDCB->SyncOffset = 0;
528: pDCB->MaxNegoPeriod = 0;
529:
530: pDCB->DevMode = pEEpromBuf->NvramTarget[target].NvmTarCfg0;
531:
532: pDCB->IdentifyMsg = MSG_IDENTIFY(pDCB->lun, ((pDCB->DevMode & TRM_DISCONNECT) != 0));
533:
534: if (((quirks & SDEV_NOWIDE) == 0) &&
535: (pDCB->DevMode & TRM_WIDE) &&
536: ((sc->sc_config & HCC_WIDE_CARD) != 0))
537: pDCB->DCBFlag |= TRM_WIDE_NEGO_16BIT;
538:
539: if (((quirks & SDEV_NOSYNC) == 0) &&
540: ((pDCB->DevMode & TRM_SYNC) != 0)) {
541: PeriodIndex = pEEpromBuf->NvramTarget[target].NvmTarPeriod & 0x07;
542: pDCB->MaxNegoPeriod = trm_clock_period[PeriodIndex];
543: }
544:
545: if (((quirks & SDEV_NOTAGS) == 0) &&
546: ((pDCB->DevMode & TRM_TAG_QUEUING) != 0) &&
547: ((pDCB->DevMode & TRM_DISCONNECT) != 0))
548: /* TODO XXXX: Every device(lun) gets to queue TagMaxNum commands? */
549: pDCB->DCBFlag |= TRM_USE_TAG_QUEUING;
550:
551: trm_SetXferParams(sc, pDCB, 0);
552: }
553:
554: /*
555: * ------------------------------------------------------------
556: * Function : trm_RecoverSRB
557: * Purpose : Moves all SRBs from Going to Waiting for all the Link DCBs
558: * Inputs : struct trm_softc * -
559: * ------------------------------------------------------------
560: */
561: void
562: trm_RecoverSRB(struct trm_softc *sc)
563: {
564: struct trm_scsi_req_q *pSRB;
565:
566: /* ASSUME we are inside splbio()/splx() */
567:
568: while ((pSRB = TAILQ_FIRST(&sc->goingSRB)) != NULL) {
569: pSRB->SRBFlag &= ~TRM_ON_GOING_SRB;
570: TAILQ_REMOVE(&sc->goingSRB, pSRB, link);
571: pSRB->SRBFlag |= TRM_ON_WAITING_SRB;
572: TAILQ_INSERT_HEAD(&sc->waitingSRB, pSRB, link);
573: }
574: }
575:
576: /*
577: * ------------------------------------------------------------
578: * Function : trm_reset
579: * Purpose : perform a hard reset on the SCSI bus (and TRM_S1040 chip).
580: * Inputs :
581: * ------------------------------------------------------------
582: */
583: void
584: trm_reset (struct trm_softc *sc)
585: {
586: const bus_space_handle_t ioh = sc->sc_iohandle;
587: const bus_space_tag_t iot = sc->sc_iotag;
588: int i, intflag;
589:
590: #ifdef TRM_DEBUG0
591: printf("%s: trm_reset", sc->sc_device.dv_xname);
592: #endif
593:
594: intflag = splbio();
595:
596: bus_space_write_1(iot, ioh, TRM_S1040_DMA_INTEN, 0);
597: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_INTEN, 0);
598:
599: trm_ResetSCSIBus(sc);
600: for (i = 0; i < 500; i++)
601: DELAY(1000);
602:
603: /*
604: * Enable all SCSI interrupts except EN_SCAM
605: */
606: bus_space_write_1(iot, ioh,
607: TRM_S1040_SCSI_INTEN,
608: (EN_SELECT | EN_SELTIMEOUT | EN_DISCONNECT | EN_RESELECTED |
609: EN_SCSIRESET | EN_BUSSERVICE | EN_CMDDONE));
610: /*
611: * Enable DMA interrupt
612: */
613: bus_space_write_1(iot, ioh, TRM_S1040_DMA_INTEN, EN_SCSIINTR);
614: /*
615: * Clear DMA FIFO
616: */
617: bus_space_write_1(iot, ioh, TRM_S1040_DMA_CONTROL, CLRXFIFO);
618: /*
619: * Clear SCSI FIFO
620: */
621: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_CLRFIFO);
622:
623: trm_ResetAllDevParam(sc);
624: trm_GoingSRB_Done(sc);
625: sc->pActiveDCB = NULL;
626:
627: /*
628: * RESET_DETECT, RESET_DONE, RESET_DEV
629: */
630: sc->sc_Flag = 0;
631: trm_StartWaitingSRB(sc);
632:
633: splx(intflag);
634: }
635:
636: /*
637: * ------------------------------------------------------------
638: * Function : trm_timeout
639: * Purpose : Prints a timeout message and aborts the timed out SCSI request
640: * Inputs : void * - A struct trm_scsi_req_q * structure pointer
641: * ------------------------------------------------------------
642: */
643: void
644: trm_timeout(void *arg1)
645: {
646: struct trm_scsi_req_q *pSRB;
647: struct scsi_xfer *xs;
648: struct trm_softc *sc;
649:
650: pSRB = (struct trm_scsi_req_q *)arg1;
651: xs = pSRB->xs;
652:
653: if (xs != NULL) {
654: sc = xs->sc_link->adapter_softc;
655: sc_print_addr(xs->sc_link);
656: printf("%s: SCSI OpCode 0x%02x for target %d lun %d timed out\n",
657: sc->sc_device.dv_xname, xs->cmd->opcode,
658: xs->sc_link->target, xs->sc_link->lun);
659: pSRB->SRBFlag |= TRM_SCSI_TIMED_OUT;
660: trm_FinishSRB(sc, pSRB);
661: trm_StartWaitingSRB(sc);
662: }
663: #ifdef TRM_DEBUG0
664: else
665: printf("%s: trm_timeout called with xs == NULL\n",
666: sc->sc_device.dv_xname);
667: #endif
668: }
669:
670: /*
671: * ------------------------------------------------------------
672: * Function : trm_StartSRB
673: * Purpose : Send the commands in the SRB to the device
674: * Inputs : struct trm_softc * -
675: * struct trm_scsi_req_q * -
676: * Return : 0 - SCSI processor is unoccupied
677: * 1 - SCSI processor is occupied with an SRB
678: * ------------------------------------------------------------
679: */
680: int
681: trm_StartSRB(struct trm_softc *sc, struct trm_scsi_req_q *pSRB)
682: {
683: const bus_space_handle_t ioh = sc->sc_iohandle;
684: const bus_space_tag_t iot = sc->sc_iotag;
685: struct trm_dcb *pDCB = pSRB->pSRBDCB;
686: u_int32_t tag_mask;
687: u_int8_t tag_id, scsicommand;
688:
689: #ifdef TRM_DEBUG0
690: printf("%s: trm_StartSRB. sc = %p, pDCB = %p, pSRB = %p\n",
691: sc->sc_device.dv_xname, sc, pDCB, pSRB);
692: #endif
693: /*
694: * If the queue is full or the SCSI processor has a pending interrupt
695: * then try again later.
696: */
697: if ((pDCB->DCBFlag & TRM_QUEUE_FULL) || (bus_space_read_2(iot, ioh,
698: TRM_S1040_SCSI_STATUS) & SCSIINTERRUPT))
699: return (1);
700:
701: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_HOSTID, sc->sc_AdaptSCSIID);
702: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_TARGETID, pDCB->target);
703: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_SYNC, pDCB->SyncPeriod);
704: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_OFFSET, pDCB->SyncOffset);
705:
706: if ((sc->pDCB[pDCB->target][0]->sc_link != NULL) &&
707: ((sc->pDCB[pDCB->target][0]->DCBFlag & TRM_QUIRKS_VALID) == 0)) {
708: sc->pDCB[pDCB->target][0]->DCBFlag |= TRM_QUIRKS_VALID;
709: trm_ResetDevParam(sc, sc->pDCB[pDCB->target][0], sc->pDCB[pDCB->target][0]->sc_link->quirks);
710: }
711:
712: /*
713: * Flush FIFO
714: */
715: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_CLRFIFO);
716:
717: sc->MsgCnt = 1;
718: sc->MsgBuf[0] = pDCB->IdentifyMsg;
719: if (((pSRB->xs->flags & SCSI_POLL) != 0) ||
720: (pSRB->CmdBlock[0] == INQUIRY) ||
721: (pSRB->CmdBlock[0] == REQUEST_SENSE))
722: sc->MsgBuf[0] &= ~MSG_IDENTIFY_DISCFLAG;
723:
724: scsicommand = SCMD_SEL_ATN;
725:
726: if ((pDCB->DCBFlag & (TRM_WIDE_NEGO_ENABLE | TRM_SYNC_NEGO_ENABLE)) != 0) {
727: scsicommand = SCMD_SEL_ATNSTOP;
728: pSRB->SRBState = TRM_MSGOUT;
729:
730: } else if ((pDCB->DCBFlag & TRM_USE_TAG_QUEUING) == 0) {
731: pDCB->DCBFlag |= TRM_QUEUE_FULL;
732:
733: } else if ((sc->MsgBuf[0] & MSG_IDENTIFY_DISCFLAG) != 0) {
734: if (pSRB->TagNumber == TRM_NO_TAG) {
735: for (tag_id=1, tag_mask=2; tag_id < 32; tag_id++, tag_mask <<= 1)
736: if ((tag_mask & pDCB->TagMask) == 0) {
737: pDCB->TagMask |= tag_mask;
738: pSRB->TagNumber = tag_id;
739: break;
740: }
741:
742: if (tag_id >= 32) {
743: pDCB->DCBFlag |= TRM_QUEUE_FULL;
744: sc->MsgCnt = 0;
745: return 1;
746: }
747: }
748:
749: /* TODO XXXX: Should send ORDERED_Q_TAG if metadata (non-block) i/o!? */
750: sc->MsgBuf[sc->MsgCnt++] = MSG_SIMPLE_Q_TAG;
751: sc->MsgBuf[sc->MsgCnt++] = pSRB->TagNumber;
752:
753: scsicommand = SCMD_SEL_ATN3;
754: }
755:
756: pSRB->SRBState = TRM_START;
757: pSRB->ScsiPhase = PH_BUS_FREE; /* SCSI bus free Phase */
758: sc->pActiveDCB = pDCB;
759: pDCB->pActiveSRB = pSRB;
760:
761: if (sc->MsgCnt > 0) {
762: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_FIFO, sc->MsgBuf[0]);
763: if (sc->MsgCnt > 1) {
764: DELAY(30);
765: bus_space_write_multi_1(iot, ioh, TRM_S1040_SCSI_FIFO, &sc->MsgBuf[1], sc->MsgCnt - 1);
766: }
767: sc->MsgCnt = 0;
768: }
769:
770: /*
771: * it's important for atn stop
772: */
773: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_DATALATCH | DO_HWRESELECT);
774: /*
775: * SCSI command
776: */
777: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, scsicommand);
778:
779: return 0;
780: }
781:
782: /*
783: * ------------------------------------------------------------
784: * Function : trm_Interrupt
785: * Purpose : Catch an interrupt from the adapter
786: * Process pending device interrupts.
787: * Inputs : void * - struct trm_softc * structure pointer
788: * ------------------------------------------------------------
789: */
790: int
791: trm_Interrupt(void *vsc)
792: {
793: void (*stateV)(struct trm_softc *, struct trm_scsi_req_q *, u_int8_t *);
794: struct trm_scsi_req_q *pSRB;
795: bus_space_handle_t ioh;
796: struct trm_softc *sc = (struct trm_softc *)vsc;
797: bus_space_tag_t iot;
798: u_int16_t phase;
799: u_int8_t scsi_status, scsi_intstatus;
800: int intflag;
801:
802: intflag = splbio();
803:
804: if (sc == NULL) {
805: splx(intflag);
806: return 0;
807: }
808:
809: ioh = sc->sc_iohandle;
810: iot = sc->sc_iotag;
811:
812: scsi_status = bus_space_read_2(iot, ioh, TRM_S1040_SCSI_STATUS);
813: if (!(scsi_status & SCSIINTERRUPT)) {
814: splx(intflag);
815: return 0;
816: }
817: scsi_intstatus = bus_space_read_1(iot, ioh, TRM_S1040_SCSI_INTSTATUS);
818:
819: #ifdef TRM_DEBUG0
820: printf("%s: trm_interrupt - scsi_status=0x%02x, scsi_intstatus=0x%02x\n",
821: sc->sc_device.dv_xname, scsi_status, scsi_intstatus);
822: #endif
823: if ((scsi_intstatus & (INT_SELTIMEOUT | INT_DISCONNECT)) != 0)
824: trm_Disconnect(sc);
825:
826: else if ((scsi_intstatus & INT_RESELECTED) != 0)
827: trm_Reselect(sc);
828:
829: else if ((scsi_intstatus & INT_SCSIRESET) != 0)
830: trm_ScsiRstDetect(sc);
831:
832: else if ((sc->pActiveDCB != NULL) && ((scsi_intstatus & (INT_BUSSERVICE | INT_CMDDONE)) != 0)) {
833: pSRB = sc->pActiveDCB->pActiveSRB;
834: /*
835: * software sequential machine
836: */
837: phase = (u_int16_t) pSRB->ScsiPhase; /* phase: */
838: /*
839: * 62037 or 62137
840: * call trm_SCSI_phase0[]... "phase entry"
841: * handle every phase before start transfer
842: */
843: stateV = trm_SCSI_phase0[phase];
844: stateV(sc, pSRB, &scsi_status);
845: /*
846: * if any exception occurred
847: * scsi_status will be modified to bus free phase
848: * new scsi_status transfer out from previous stateV
849: */
850: /*
851: * phase:0,1,2,3,4,5,6,7
852: */
853: pSRB->ScsiPhase = scsi_status & PHASEMASK;
854: phase = (u_int16_t) scsi_status & PHASEMASK;
855: /*
856: * call trm_SCSI_phase1[]... "phase entry"
857: * handle every phase do transfer
858: */
859: stateV = trm_SCSI_phase1[phase];
860: stateV(sc, pSRB, &scsi_status);
861:
862: } else {
863: splx(intflag);
864: return 0;
865: }
866:
867: splx(intflag);
868: return 1;
869: }
870:
871: /*
872: * ------------------------------------------------------------
873: * Function : trm_MsgOutPhase0
874: * Purpose : Check the state machine before sending a message out
875: * Inputs : struct trm_softc * -
876: * struct trm_scsi_req_q * -
877: * u_int8_t * - scsi status, set to PH_BUS_FREE if not ready
878: * ------------------------------------------------------------
879: */
880: void
881: trm_MsgOutPhase0(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
882: {
883: switch (pSRB->SRBState) {
884: case TRM_UNEXPECT_RESEL:
885: case TRM_ABORT_SENT:
886: *pscsi_status = PH_BUS_FREE; /* initial phase */
887: break;
888:
889: default:
890: break;
891: }
892: }
893:
894: /*
895: * ------------------------------------------------------------
896: * Function : trm_MsgOutPhase1
897: * Purpose : Write the message out to the bus
898: * Inputs : struct trm_softc * -
899: * struct trm_scsi_req_q * -
900: * u_int8_t * - unused
901: * ------------------------------------------------------------
902: */
903: void
904: trm_MsgOutPhase1(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
905: {
906: const bus_space_handle_t ioh = sc->sc_iohandle;
907: const bus_space_tag_t iot = sc->sc_iotag;
908: struct trm_dcb *pDCB = sc->pActiveDCB;
909:
910: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_CLRFIFO);
911:
912: if ((pDCB->DCBFlag & TRM_WIDE_NEGO_ENABLE) != 0) {
913: /*
914: * WIDE DATA TRANSFER REQUEST code (03h)
915: */
916: pDCB->DCBFlag &= ~TRM_WIDE_NEGO_ENABLE;
917: pDCB->DCBFlag |= TRM_DOING_WIDE_NEGO;
918:
919: sc->MsgBuf[0] = pDCB->IdentifyMsg & ~MSG_IDENTIFY_DISCFLAG;
920: sc->MsgBuf[1] = MSG_EXTENDED;
921: sc->MsgBuf[2] = MSG_EXT_WDTR_LEN;
922: sc->MsgBuf[3] = MSG_EXT_WDTR;
923:
924: if ((pDCB->DCBFlag & TRM_WIDE_NEGO_16BIT) == 0)
925: sc->MsgBuf[4] = MSG_EXT_WDTR_BUS_8_BIT;
926: else
927: sc->MsgBuf[4] = MSG_EXT_WDTR_BUS_16_BIT;
928:
929: sc->MsgCnt = 5;
930:
931: } else if ((pDCB->DCBFlag & TRM_SYNC_NEGO_ENABLE) != 0) {
932:
933: pDCB->DCBFlag &= ~TRM_SYNC_NEGO_ENABLE;
934: pDCB->DCBFlag |= TRM_DOING_SYNC_NEGO;
935:
936: sc->MsgCnt = 0;
937:
938: if ((pDCB->DCBFlag & TRM_WIDE_NEGO_DONE) == 0)
939: sc->MsgBuf[sc->MsgCnt++] = pDCB->IdentifyMsg & ~MSG_IDENTIFY_DISCFLAG;
940:
941: sc->MsgBuf[sc->MsgCnt++] = MSG_EXTENDED;
942: sc->MsgBuf[sc->MsgCnt++] = MSG_EXT_SDTR_LEN;
943: sc->MsgBuf[sc->MsgCnt++] = MSG_EXT_SDTR;
944: sc->MsgBuf[sc->MsgCnt++] = pDCB->MaxNegoPeriod;
945:
946: if (pDCB->MaxNegoPeriod > 0)
947: sc->MsgBuf[sc->MsgCnt++] = TRM_MAX_SYNC_OFFSET;
948: else
949: sc->MsgBuf[sc->MsgCnt++] = 0;
950: }
951:
952: if (sc->MsgCnt > 0) {
953: bus_space_write_multi_1(iot, ioh, TRM_S1040_SCSI_FIFO, &sc->MsgBuf[0], sc->MsgCnt);
954: if (sc->MsgBuf[0] == MSG_ABORT)
955: pSRB->SRBState = TRM_ABORT_SENT;
956: sc->MsgCnt = 0;
957: }
958: /*
959: * it's important for atn stop
960: */
961: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
962: /*
963: * Transfer information out
964: */
965: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT);
966: }
967:
968: /*
969: * ------------------------------------------------------------
970: * Function : trm_CommandPhase1
971: * Purpose : Send commands to bus
972: * Inputs :
973: * ------------------------------------------------------------
974: */
975: void
976: trm_CommandPhase1(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
977: {
978: const bus_space_handle_t ioh = sc->sc_iohandle;
979: const bus_space_tag_t iot = sc->sc_iotag;
980:
981: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_CLRATN | DO_CLRFIFO);
982:
983: bus_space_write_multi_1(iot, ioh, TRM_S1040_SCSI_FIFO, &pSRB->CmdBlock[0], pSRB->ScsiCmdLen);
984:
985: pSRB->SRBState = TRM_COMMAND;
986: /*
987: * it's important for atn stop
988: */
989: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
990: /*
991: * Transfer information out
992: */
993: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT);
994: }
995:
996: /*
997: * ------------------------------------------------------------
998: * Function : trm_DataOutPhase0
999: * Purpose : Ready for Data Out, clear FIFO
1000: * Inputs : u_int8_t * - SCSI status, used but not set
1001: * ------------------------------------------------------------
1002: */
1003: void
1004: trm_DataOutPhase0(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
1005: {
1006: const bus_space_handle_t ioh = sc->sc_iohandle;
1007: const bus_space_tag_t iot = sc->sc_iotag;
1008: struct SGentry *pseg;
1009: struct trm_dcb *pDCB;
1010: u_int32_t dLeftCounter, TempSRBXferredLength;
1011: u_int16_t scsi_status;
1012: u_int8_t TempDMAstatus, SGIndexTemp;
1013:
1014: dLeftCounter = 0;
1015:
1016: pDCB = pSRB->pSRBDCB;
1017: scsi_status = *pscsi_status;
1018:
1019: if (pSRB->SRBState != TRM_XFERPAD) {
1020: if ((scsi_status & PARITYERROR) != 0)
1021: pSRB->SRBFlag |= TRM_PARITY_ERROR;
1022: if ((scsi_status & SCSIXFERDONE) == 0) {
1023: /*
1024: * when data transfer from DMA FIFO to SCSI FIFO
1025: * if there was some data left in SCSI FIFO
1026: */
1027: dLeftCounter = (u_int32_t)(bus_space_read_1(
1028: iot, ioh, TRM_S1040_SCSI_FIFOCNT) & 0x1F);
1029: if (pDCB->SyncPeriod & WIDE_SYNC) {
1030: /*
1031: * if WIDE scsi SCSI FIFOCNT unit is word
1032: * so need to * 2
1033: */
1034: dLeftCounter <<= 1;
1035: }
1036: }
1037: /*
1038: * calculate all the residue data that not yet transferred
1039: * SCSI transfer counter + left in SCSI FIFO data
1040: *
1041: * .....TRM_S1040_SCSI_COUNTER (24bits)
1042: * The counter always decrement by one for every SCSI byte
1043: * transfer.
1044: * .....TRM_S1040_SCSI_FIFOCNT ( 5bits)
1045: * The counter is SCSI FIFO offset counter
1046: */
1047: dLeftCounter += bus_space_read_4(iot, ioh,
1048: TRM_S1040_SCSI_COUNTER);
1049: if (dLeftCounter == 1) {
1050: dLeftCounter = 0;
1051: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL,
1052: DO_CLRFIFO);
1053: }
1054: if (dLeftCounter == 0 ||
1055: (scsi_status & SCSIXFERCNT_2_ZERO) != 0) {
1056: TempDMAstatus = bus_space_read_1(iot,
1057: ioh, TRM_S1040_DMA_STATUS);
1058: while ((TempDMAstatus & DMAXFERCOMP) == 0) {
1059: TempDMAstatus = bus_space_read_1(iot,
1060: ioh, TRM_S1040_DMA_STATUS);
1061: }
1062: pSRB->SRBTotalXferLength = 0;
1063: } else {
1064: /*
1065: * Update SG list
1066: */
1067: /*
1068: * if transfer not yet complete
1069: * there were some data residue in SCSI FIFO or
1070: * SCSI transfer counter not empty
1071: */
1072: if (pSRB->SRBTotalXferLength != dLeftCounter) {
1073: /*
1074: * data that had transferred length
1075: */
1076: TempSRBXferredLength = pSRB->SRBTotalXferLength
1077: - dLeftCounter;
1078: /*
1079: * next time to be transferred length
1080: */
1081: pSRB->SRBTotalXferLength = dLeftCounter;
1082: /*
1083: * parsing from last time disconnect SRBSGIndex
1084: */
1085: pseg = &pSRB->SegmentX[pSRB->SRBSGIndex];
1086: for (SGIndexTemp = pSRB->SRBSGIndex;
1087: SGIndexTemp < pSRB->SRBSGCount;
1088: SGIndexTemp++) {
1089: /*
1090: * find last time which SG transfer be
1091: * disconnect
1092: */
1093: if (TempSRBXferredLength >= pseg->length)
1094: TempSRBXferredLength -= pseg->length;
1095: else {
1096: /*
1097: * update last time disconnected
1098: * SG list
1099: */
1100: /*
1101: * residue data length
1102: */
1103: pseg->length -=
1104: TempSRBXferredLength;
1105: /*
1106: * residue data pointer
1107: */
1108: pseg->address +=
1109: TempSRBXferredLength;
1110: pSRB->SRBSGIndex = SGIndexTemp;
1111: break;
1112: }
1113: pseg++;
1114: }
1115: }
1116: }
1117: }
1118: bus_space_write_1(iot, ioh, TRM_S1040_DMA_CONTROL, STOPDMAXFER);
1119: }
1120:
1121: /*
1122: * ------------------------------------------------------------
1123: * Function : trm_DataOutPhase1
1124: * Purpose : Transfers data out, calls trm_DataIO_transfer
1125: * Inputs :
1126: * ------------------------------------------------------------
1127: */
1128: void
1129: trm_DataOutPhase1(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
1130: {
1131: trm_DataIO_transfer(sc, pSRB, XFERDATAOUT);
1132: }
1133:
1134: /*
1135: * ------------------------------------------------------------
1136: * Function : trm_DataInPhase0
1137: * Purpose : Prepare for reading data in from bus
1138: * Inputs :
1139: * ------------------------------------------------------------
1140: */
1141: void
1142: trm_DataInPhase0(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
1143: {
1144: const bus_space_handle_t ioh = sc->sc_iohandle;
1145: const bus_space_tag_t iot = sc->sc_iotag;
1146: struct SGentry *pseg;
1147: u_int32_t TempSRBXferredLength, dLeftCounter;
1148: u_int16_t scsi_status;
1149: u_int8_t SGIndexTemp;
1150:
1151: dLeftCounter = 0;
1152:
1153: scsi_status = *pscsi_status;
1154: if (pSRB->SRBState != TRM_XFERPAD) {
1155: if ((scsi_status & PARITYERROR) != 0)
1156: pSRB->SRBFlag |= TRM_PARITY_ERROR;
1157: dLeftCounter += bus_space_read_4(iot, ioh,
1158: TRM_S1040_SCSI_COUNTER);
1159: if (dLeftCounter == 0 ||
1160: (scsi_status & SCSIXFERCNT_2_ZERO) != 0) {
1161: while ((bus_space_read_1(iot, ioh, TRM_S1040_DMA_STATUS) & DMAXFERCOMP) == 0)
1162: ;
1163: pSRB->SRBTotalXferLength = 0;
1164: } else {
1165: /*
1166: * phase changed
1167: *
1168: * parsing the case:
1169: * when a transfer not yet complete
1170: * but be disconnected by uper layer
1171: * if transfer not yet complete
1172: * there were some data residue in SCSI FIFO or
1173: * SCSI transfer counter not empty
1174: */
1175: if (pSRB->SRBTotalXferLength != dLeftCounter) {
1176: /*
1177: * data that had transferred length
1178: */
1179: TempSRBXferredLength = pSRB->SRBTotalXferLength
1180: - dLeftCounter;
1181: /*
1182: * next time to be transferred length
1183: */
1184: pSRB->SRBTotalXferLength = dLeftCounter;
1185: /*
1186: * parsing from last time disconnect SRBSGIndex
1187: */
1188: pseg = &pSRB->SegmentX[pSRB->SRBSGIndex];
1189: for (SGIndexTemp = pSRB->SRBSGIndex;
1190: SGIndexTemp < pSRB->SRBSGCount;
1191: SGIndexTemp++) {
1192: /*
1193: * find last time which SG transfer be
1194: * disconnect
1195: */
1196: if (TempSRBXferredLength >=
1197: pseg->length) {
1198: TempSRBXferredLength -= pseg->length;
1199: } else {
1200: /*
1201: * update last time disconnected
1202: * SG list
1203: *
1204: * residue data length
1205: */
1206: pseg->length -= TempSRBXferredLength;
1207: /*
1208: * residue data pointer
1209: */
1210: pseg->address += TempSRBXferredLength;
1211: pSRB->SRBSGIndex = SGIndexTemp;
1212: break;
1213: }
1214: pseg++;
1215: }
1216: }
1217: }
1218: }
1219: }
1220:
1221: /*
1222: * ------------------------------------------------------------
1223: * Function : trm_DataInPhase1
1224: * Purpose : Transfer data in from bus, calls trm_DataIO_transfer
1225: * Inputs :
1226: * ------------------------------------------------------------
1227: */
1228: void
1229: trm_DataInPhase1(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
1230: {
1231: trm_DataIO_transfer(sc, pSRB, XFERDATAIN);
1232: }
1233:
1234: /*
1235: * ------------------------------------------------------------
1236: * Function : trm_DataIO_transfer
1237: * Purpose :
1238: * Inputs :
1239: * ------------------------------------------------------------
1240: */
1241: void
1242: trm_DataIO_transfer(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int16_t ioDir)
1243: {
1244: const bus_space_handle_t ioh = sc->sc_iohandle;
1245: const bus_space_tag_t iot = sc->sc_iotag;
1246: struct trm_dcb *pDCB = pSRB->pSRBDCB;
1247: u_int8_t bval;
1248:
1249: if (pSRB->SRBSGIndex < pSRB->SRBSGCount) {
1250: if (pSRB->SRBTotalXferLength != 0) {
1251: /*
1252: * load what physical address of Scatter/Gather list
1253: * table want to be transfer
1254: */
1255: pSRB->SRBState = TRM_DATA_XFER;
1256: bus_space_write_4(iot, ioh, TRM_S1040_DMA_XHIGHADDR, 0);
1257: bus_space_write_4(iot, ioh,
1258: TRM_S1040_DMA_XLOWADDR, (pSRB->SRBSGPhyAddr +
1259: ((u_int32_t)pSRB->SRBSGIndex << 3)));
1260: /*
1261: * load how many bytes in the Scatter/Gather list table
1262: */
1263: bus_space_write_4(iot, ioh, TRM_S1040_DMA_XCNT,
1264: ((u_int32_t)(pSRB->SRBSGCount -
1265: pSRB->SRBSGIndex) << 3));
1266: /*
1267: * load total transfer length (24bits,
1268: * pSRB->SRBTotalXferLength) max value 16Mbyte
1269: */
1270: bus_space_write_4(iot, ioh,
1271: TRM_S1040_SCSI_COUNTER, pSRB->SRBTotalXferLength);
1272: /*
1273: * Start DMA transfer
1274: */
1275: bus_space_write_2(iot,ioh,TRM_S1040_DMA_COMMAND, ioDir);
1276: /* bus_space_write_2(iot, ioh,
1277: TRM_S1040_DMA_CONTROL, STARTDMAXFER);*/
1278: /*
1279: * Set the transfer bus and direction
1280: */
1281: bval = ioDir == XFERDATAOUT ? SCMD_DMA_OUT :SCMD_DMA_IN;
1282: } else {
1283: /*
1284: * xfer pad
1285: */
1286: if (pSRB->SRBSGCount)
1287: pSRB->AdaptStatus = TRM_OVER_UNDER_RUN;
1288:
1289: if (pDCB->SyncPeriod & WIDE_SYNC) {
1290: bus_space_write_4(iot, ioh,
1291: TRM_S1040_SCSI_COUNTER, 2);
1292: } else {
1293: bus_space_write_4(iot, ioh,
1294: TRM_S1040_SCSI_COUNTER, 1);
1295: }
1296:
1297: if (ioDir == XFERDATAOUT) {
1298: bus_space_write_2(iot,
1299: ioh, TRM_S1040_SCSI_FIFO, 0);
1300: } else {
1301: bus_space_read_2(iot,
1302: ioh, TRM_S1040_SCSI_FIFO);
1303: }
1304: pSRB->SRBState = TRM_XFERPAD;
1305: /*
1306: * Set the transfer bus and direction
1307: */
1308: bval = ioDir == XFERDATAOUT ? SCMD_FIFO_OUT : SCMD_FIFO_IN;
1309: }
1310: /*
1311: * it's important for atn stop
1312: */
1313: bus_space_write_2(iot,ioh,TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
1314: /*
1315: * Tell the bus to do the transfer
1316: */
1317: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, bval);
1318: }
1319: }
1320:
1321: /*
1322: * ------------------------------------------------------------
1323: * Function : trm_StatusPhase0
1324: * Purpose : Update Target Status with data from SCSI FIFO
1325: * Inputs : u_int8_t * - Set to PH_BUS_FREE
1326: * ------------------------------------------------------------
1327: */
1328: void
1329: trm_StatusPhase0(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
1330: {
1331: const bus_space_handle_t ioh = sc->sc_iohandle;
1332: const bus_space_tag_t iot = sc->sc_iotag;
1333:
1334: pSRB->TargetStatus = bus_space_read_1(iot, ioh, TRM_S1040_SCSI_FIFO);
1335:
1336: pSRB->SRBState = TRM_COMPLETED;
1337: /*
1338: * initial phase
1339: */
1340: *pscsi_status = PH_BUS_FREE;
1341: /*
1342: * it's important for atn stop
1343: */
1344: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
1345: /*
1346: * Tell bus that the message was accepted
1347: */
1348: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, SCMD_MSGACCEPT);
1349: }
1350:
1351: /*
1352: * ------------------------------------------------------------
1353: * Function : trm_StatusPhase1
1354: * Purpose : Clear FIFO of DMA and SCSI
1355: * Inputs :
1356: * ------------------------------------------------------------
1357: */
1358: void
1359: trm_StatusPhase1(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
1360: {
1361: const bus_space_handle_t ioh = sc->sc_iohandle;
1362: const bus_space_tag_t iot = sc->sc_iotag;
1363:
1364: if ((bus_space_read_2(iot, ioh, TRM_S1040_DMA_COMMAND) & 0x0001) != 0) {
1365: if ((bus_space_read_1(iot, ioh, TRM_S1040_SCSI_FIFOCNT) & 0x40)
1366: == 0) {
1367: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL,
1368: DO_CLRFIFO);
1369: }
1370: if ((bus_space_read_2(iot, ioh,
1371: TRM_S1040_DMA_FIFOCNT) & 0x8000) == 0) {
1372: bus_space_write_1(iot, ioh,
1373: TRM_S1040_DMA_CONTROL, CLRXFIFO);
1374: }
1375: } else {
1376: if ((bus_space_read_2(iot, ioh,
1377: TRM_S1040_DMA_FIFOCNT) & 0x8000) == 0) {
1378: bus_space_write_1(iot, ioh,
1379: TRM_S1040_DMA_CONTROL, CLRXFIFO);
1380: }
1381: if ((bus_space_read_1(iot, ioh,
1382: TRM_S1040_SCSI_FIFOCNT) & 0x40) == 0) {
1383: bus_space_write_2(iot, ioh,
1384: TRM_S1040_SCSI_CONTROL, DO_CLRFIFO);
1385: }
1386: }
1387: pSRB->SRBState = TRM_STATUS;
1388: /*
1389: * it's important for atn stop
1390: */
1391: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
1392: /*
1393: * Tell the bus that the command is complete
1394: */
1395: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, SCMD_COMP);
1396: }
1397:
1398: /*
1399: * ------------------------------------------------------------
1400: * Function : trm_MsgInPhase0
1401: * Purpose :
1402: * Inputs :
1403: *
1404: * extended message codes:
1405: * code description
1406: * ---- -----------
1407: * 02h Reserved
1408: * 00h MODIFY DATA POINTER
1409: * 01h SYNCHRONOUS DATA TRANSFER REQUEST
1410: * 03h WIDE DATA TRANSFER REQUEST
1411: * 04h - 7Fh Reserved
1412: * 80h - FFh Vendor specific
1413: *
1414: * ------------------------------------------------------------
1415: */
1416: void
1417: trm_MsgInPhase0(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
1418: {
1419: const bus_space_handle_t ioh = sc->sc_iohandle;
1420: const bus_space_tag_t iot = sc->sc_iotag;
1421: struct trm_dcb *pDCB;
1422: u_int8_t message_in_code, bIndex, message_in_tag_id;
1423:
1424: pDCB = sc->pActiveDCB;
1425:
1426: message_in_code = bus_space_read_1(iot, ioh, TRM_S1040_SCSI_FIFO);
1427:
1428: if (pSRB->SRBState != TRM_EXTEND_MSGIN) {
1429: switch (message_in_code) {
1430: case MSG_DISCONNECT:
1431: pSRB->SRBState = TRM_DISCONNECTED;
1432: break;
1433:
1434: case MSG_EXTENDED:
1435: case MSG_SIMPLE_Q_TAG:
1436: case MSG_HEAD_OF_Q_TAG:
1437: case MSG_ORDERED_Q_TAG:
1438: pSRB->SRBState = TRM_EXTEND_MSGIN;
1439: /*
1440: * extended message (01h)
1441: */
1442: bzero(&sc->MsgBuf[0], sizeof(sc->MsgBuf));
1443: sc->MsgBuf[0] = message_in_code;
1444: sc->MsgCnt = 1;
1445: /*
1446: * extended message length (n)
1447: */
1448: break;
1449:
1450: case MSG_MESSAGE_REJECT:
1451: /*
1452: * Reject message
1453: */
1454: if ((pDCB->DCBFlag & TRM_DOING_WIDE_NEGO) != 0) {
1455: /*
1456: * do wide nego reject
1457: */
1458: pDCB = pSRB->pSRBDCB;
1459:
1460: pDCB->DCBFlag &= ~TRM_DOING_WIDE_NEGO;
1461: pDCB->DCBFlag |= TRM_WIDE_NEGO_DONE;
1462:
1463: if ((pDCB->DCBFlag & TRM_SYNC_NEGO_ENABLE) != 0) {
1464: /*
1465: * Set ATN, in case ATN was clear
1466: */
1467: pSRB->SRBState = TRM_MSGOUT;
1468: bus_space_write_2(iot, ioh,
1469: TRM_S1040_SCSI_CONTROL, DO_SETATN);
1470: } else {
1471: /*
1472: * Clear ATN
1473: */
1474: bus_space_write_2(iot, ioh,
1475: TRM_S1040_SCSI_CONTROL, DO_CLRATN);
1476: }
1477:
1478: } else if ((pDCB->DCBFlag & TRM_DOING_SYNC_NEGO) != 0) {
1479: /*
1480: * do sync nego reject
1481: */
1482: pDCB = pSRB->pSRBDCB;
1483:
1484: pDCB->DCBFlag &= ~TRM_DOING_SYNC_NEGO;
1485:
1486: pDCB->SyncPeriod = 0;
1487: pDCB->SyncOffset = 0;
1488:
1489: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_CLRATN);
1490: goto re_prog;
1491: }
1492: break;
1493:
1494: case MSG_IGN_WIDE_RESIDUE:
1495: bus_space_write_4(iot, ioh, TRM_S1040_SCSI_COUNTER, 1);
1496: bus_space_read_1(iot, ioh, TRM_S1040_SCSI_FIFO);
1497: break;
1498:
1499: default:
1500: break;
1501: }
1502:
1503: } else {
1504:
1505: /*
1506: * We are collecting an extended message. Save the latest byte and then
1507: * check to see if the message is complete. If so, process it.
1508: */
1509: sc->MsgBuf[sc->MsgCnt++] = message_in_code;
1510: #ifdef TRM_DEBUG0
1511: printf("%s: sc->MsgBuf = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
1512: sc->sc_device.dv_xname,
1513: sc->MsgBuf[0], sc->MsgBuf[1], sc->MsgBuf[2], sc->MsgBuf[3], sc->MsgBuf[4], sc->MsgBuf[5] );
1514: #endif
1515: switch (sc->MsgBuf[0]) {
1516: case MSG_SIMPLE_Q_TAG:
1517: case MSG_HEAD_OF_Q_TAG:
1518: case MSG_ORDERED_Q_TAG:
1519: if (sc->MsgCnt == 2) {
1520: pSRB->SRBState = TRM_FREE;
1521: message_in_tag_id = sc->MsgBuf[1];
1522: sc->MsgCnt = 0;
1523: TAILQ_FOREACH(pSRB, &sc->goingSRB, link) {
1524: if ((pSRB->pSRBDCB == pDCB) && (pSRB->TagNumber == message_in_tag_id))
1525: break;
1526: }
1527: if ((pSRB != NULL) && (pSRB->SRBState == TRM_DISCONNECTED)) {
1528: pDCB->pActiveSRB = pSRB;
1529: pSRB->SRBState = TRM_DATA_XFER;
1530: } else {
1531: pSRB = &sc->SRB[0];
1532: pSRB->SRBState = TRM_UNEXPECT_RESEL;
1533: pDCB->pActiveSRB = pSRB;
1534: trm_EnableMsgOut(sc, MSG_ABORT_TAG);
1535: }
1536: }
1537: break;
1538:
1539: case MSG_EXTENDED:
1540: /* TODO XXXX: Correctly handling target initiated negotiations? */
1541: if ((sc->MsgBuf[2] == MSG_EXT_WDTR) && (sc->MsgCnt == 4)) {
1542: /*
1543: * ======================================
1544: * WIDE DATA TRANSFER REQUEST
1545: * ======================================
1546: * byte 0 : Extended message (01h)
1547: * byte 1 : Extended message length (02h)
1548: * byte 2 : WIDE DATA TRANSFER code (03h)
1549: * byte 3 : Transfer width exponent
1550: */
1551:
1552: pSRB->SRBState = TRM_FREE;
1553: pDCB->DCBFlag &= ~(TRM_WIDE_NEGO_ENABLE | TRM_DOING_WIDE_NEGO);
1554:
1555: if (sc->MsgBuf[1] != MSG_EXT_WDTR_LEN)
1556: goto reject_offer;
1557:
1558: switch (sc->MsgBuf[3]) {
1559: case MSG_EXT_WDTR_BUS_32_BIT:
1560: if ((pDCB->DCBFlag & TRM_WIDE_NEGO_16BIT) == 0)
1561: sc->MsgBuf[3] = MSG_EXT_WDTR_BUS_8_BIT;
1562: else
1563: sc->MsgBuf[3] = MSG_EXT_WDTR_BUS_16_BIT;
1564: break;
1565:
1566: case MSG_EXT_WDTR_BUS_16_BIT:
1567: if ((pDCB->DCBFlag & TRM_WIDE_NEGO_16BIT) == 0) {
1568: sc->MsgBuf[3] = MSG_EXT_WDTR_BUS_8_BIT;
1569: break;
1570: }
1571: pDCB->SyncPeriod |= WIDE_SYNC;
1572: /* FALL THROUGH == ACCEPT OFFER */
1573:
1574: case MSG_EXT_WDTR_BUS_8_BIT:
1575: pSRB->SRBState = TRM_MSGOUT;
1576: pDCB->DCBFlag |= (TRM_SYNC_NEGO_ENABLE | TRM_WIDE_NEGO_DONE);
1577:
1578: if (pDCB->MaxNegoPeriod == 0) {
1579: pDCB->SyncPeriod = 0;
1580: pDCB->SyncOffset = 0;
1581: goto re_prog;
1582: }
1583: break;
1584:
1585: default:
1586: pDCB->DCBFlag &= ~TRM_WIDE_NEGO_ENABLE;
1587: pDCB->DCBFlag |= TRM_WIDE_NEGO_DONE;
1588: reject_offer:
1589: sc->MsgCnt = 1;
1590: sc->MsgBuf[0] = MSG_MESSAGE_REJECT;
1591: break;
1592: }
1593:
1594: /* Echo accepted offer, or send revised offer */
1595: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_SETATN);
1596:
1597: } else if ((sc->MsgBuf[2] == MSG_EXT_SDTR) && (sc->MsgCnt == 5)) {
1598: /*
1599: * =================================
1600: * SYNCHRONOUS DATA TRANSFER REQUEST
1601: * =================================
1602: * byte 0 : Extended message (01h)
1603: * byte 1 : Extended message length (03)
1604: * byte 2 : SYNCHRONOUS DATA TRANSFER code (01h)
1605: * byte 3 : Transfer period factor
1606: * byte 4 : REQ/ACK offset
1607: */
1608:
1609: pSRB->SRBState = TRM_FREE;
1610: pDCB->DCBFlag &= ~(TRM_SYNC_NEGO_ENABLE | TRM_DOING_SYNC_NEGO);
1611:
1612: if (sc->MsgBuf[1] != MSG_EXT_SDTR_LEN)
1613: goto reject_offer;
1614:
1615: if ((sc->MsgBuf[3] == 0) || (sc->MsgBuf[4] == 0)) {
1616: /*
1617: * Asynchronous transfers
1618: */
1619: pDCB->SyncPeriod = 0;
1620: pDCB->SyncOffset = 0;
1621:
1622: } else {
1623: /*
1624: * Synchronous transfers
1625: */
1626: /*
1627: * REQ/ACK offset
1628: */
1629: pDCB->SyncOffset = sc->MsgBuf[4];
1630:
1631: for (bIndex = 0; bIndex < 7; bIndex++)
1632: if (sc->MsgBuf[3] <= trm_clock_period[bIndex])
1633: break;
1634:
1635: pDCB->SyncPeriod |= (bIndex | ALT_SYNC);
1636: }
1637:
1638: re_prog: /*
1639: * program SCSI control register
1640: */
1641: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_SYNC, pDCB->SyncPeriod);
1642: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_OFFSET, pDCB->SyncOffset);
1643:
1644: trm_SetXferParams(sc, pDCB, (pDCB->DCBFlag & TRM_QUIRKS_VALID));
1645: }
1646: break;
1647:
1648: default:
1649: break;
1650: }
1651: }
1652:
1653: /*
1654: * initial phase
1655: */
1656: *pscsi_status = PH_BUS_FREE;
1657: /*
1658: * it's important for atn stop
1659: */
1660: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
1661: /*
1662: * Tell bus that the message was accepted
1663: */
1664: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, SCMD_MSGACCEPT);
1665: }
1666:
1667: /*
1668: * ------------------------------------------------------------
1669: * Function : trm_MsgInPhase1
1670: * Purpose : Clear the FIFO
1671: * Inputs :
1672: * ------------------------------------------------------------
1673: */
1674: void
1675: trm_MsgInPhase1(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
1676: {
1677: const bus_space_handle_t ioh = sc->sc_iohandle;
1678: const bus_space_tag_t iot = sc->sc_iotag;
1679:
1680: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_CLRFIFO);
1681: bus_space_write_4(iot, ioh, TRM_S1040_SCSI_COUNTER, 1);
1682:
1683: /*
1684: * it's important for atn stop
1685: */
1686: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
1687: /*
1688: * SCSI command
1689: */
1690: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_IN);
1691: }
1692:
1693: /*
1694: * ------------------------------------------------------------
1695: * Function : trm_Nop
1696: * Purpose : EMPTY
1697: * Inputs :
1698: * ------------------------------------------------------------
1699: */
1700: void
1701: trm_Nop(struct trm_softc *sc, struct trm_scsi_req_q *pSRB, u_int8_t *pscsi_status)
1702: {
1703: }
1704:
1705: /*
1706: * ------------------------------------------------------------
1707: * Function : trm_SetXferParams
1708: * Purpose : Set the Sync period, offset and mode for each device that has
1709: * the same target as the given one (struct trm_dcb *)
1710: * Inputs :
1711: * ------------------------------------------------------------
1712: */
1713: void
1714: trm_SetXferParams(struct trm_softc *sc, struct trm_dcb *pDCB, int print_info)
1715: {
1716: struct trm_dcb *pDCBTemp;
1717: int lun, target;
1718:
1719: /*
1720: * set all lun device's period, offset
1721: */
1722: #ifdef TRM_DEBUG0
1723: printf("%s: trm_SetXferParams\n", sc->sc_device.dv_xname);
1724: #endif
1725:
1726: target = pDCB->target;
1727: for(lun = 0; lun < TRM_MAX_LUNS; lun++) {
1728: pDCBTemp = sc->pDCB[target][lun];
1729: if (pDCBTemp != NULL) {
1730: pDCBTemp->DevMode = pDCB->DevMode;
1731: pDCBTemp->MaxNegoPeriod = pDCB->MaxNegoPeriod;
1732: pDCBTemp->SyncPeriod = pDCB->SyncPeriod;
1733: pDCBTemp->SyncOffset = pDCB->SyncOffset;
1734: pDCBTemp->DCBFlag = pDCB->DCBFlag;
1735: }
1736: }
1737:
1738: if (print_info)
1739: trm_print_info(sc, pDCB);
1740: }
1741:
1742: /*
1743: * ------------------------------------------------------------
1744: * Function : trm_Disconnect
1745: * Purpose :
1746: * Inputs :
1747: *
1748: * ---SCSI bus phase
1749: * PH_DATA_OUT 0x00 Data out phase
1750: * PH_DATA_IN 0x01 Data in phase
1751: * PH_COMMAND 0x02 Command phase
1752: * PH_STATUS 0x03 Status phase
1753: * PH_BUS_FREE 0x04 Invalid phase used as bus free
1754: * PH_BUS_FREE 0x05 Invalid phase used as bus free
1755: * PH_MSG_OUT 0x06 Message out phase
1756: * PH_MSG_IN 0x07 Message in phase
1757: * ------------------------------------------------------------
1758: */
1759: void
1760: trm_Disconnect(struct trm_softc *sc)
1761: {
1762: const bus_space_handle_t ioh = sc->sc_iohandle;
1763: struct trm_scsi_req_q *pSRB, *pNextSRB;
1764: const bus_space_tag_t iot = sc->sc_iotag;
1765: struct trm_dcb *pDCB;
1766: int j;
1767:
1768: #ifdef TRM_DEBUG0
1769: printf("%s: trm_Disconnect\n", sc->sc_device.dv_xname);
1770: #endif
1771:
1772: pDCB = sc->pActiveDCB;
1773: if (pDCB == NULL) {
1774: /* TODO: Why use a loop? Why not use DELAY(400)? */
1775: for(j = 400; j > 0; --j)
1776: DELAY(1); /* 1 msec */
1777: bus_space_write_2(iot, ioh,
1778: TRM_S1040_SCSI_CONTROL, (DO_CLRFIFO | DO_HWRESELECT));
1779: return;
1780: }
1781:
1782: pSRB = pDCB->pActiveSRB;
1783: sc->pActiveDCB = NULL;
1784: pSRB->ScsiPhase = PH_BUS_FREE; /* SCSI bus free Phase */
1785: bus_space_write_2(iot, ioh,
1786: TRM_S1040_SCSI_CONTROL, (DO_CLRFIFO | DO_HWRESELECT));
1787: DELAY(100);
1788:
1789: switch (pSRB->SRBState) {
1790: case TRM_UNEXPECT_RESEL:
1791: pSRB->SRBState = TRM_FREE;
1792: break;
1793:
1794: case TRM_ABORT_SENT:
1795: pSRB = TAILQ_FIRST(&sc->goingSRB);
1796: while (pSRB != NULL) {
1797: /*
1798: * Need to save pNextSRB because trm_FinishSRB() puts
1799: * pSRB in freeSRB queue, and thus its links no longer
1800: * point to members of the goingSRB queue. This is why
1801: * TAILQ_FOREACH() will not work for this traversal.
1802: */
1803: pNextSRB = TAILQ_NEXT(pSRB, link);
1804: if (pSRB->pSRBDCB == pDCB) {
1805: /* TODO XXXX: Is TIMED_OUT the best state to report? */
1806: pSRB->SRBFlag |= TRM_SCSI_TIMED_OUT;
1807: trm_FinishSRB(sc, pSRB);
1808: }
1809: pSRB = pNextSRB;
1810: }
1811: break;
1812:
1813: case TRM_START:
1814: case TRM_MSGOUT:
1815: /*
1816: * Selection time out
1817: */
1818: /* If not polling just keep trying until xs->stimeout expires */
1819: if ((pSRB->xs->flags & SCSI_POLL) == 0) {
1820: trm_RewaitSRB(sc, pSRB);
1821: } else {
1822: pSRB->TargetStatus = TRM_SCSI_SELECT_TIMEOUT;
1823: goto disc1;
1824: }
1825: break;
1826:
1827: case TRM_COMPLETED:
1828: disc1:
1829: /*
1830: * TRM_COMPLETED - remove id from mask of active tags
1831: */
1832: pDCB->pActiveSRB = NULL;
1833: trm_FinishSRB(sc, pSRB);
1834: break;
1835:
1836: default:
1837: break;
1838: }
1839:
1840: trm_StartWaitingSRB(sc);
1841: }
1842:
1843: /*
1844: * ------------------------------------------------------------
1845: * Function : trm_Reselect
1846: * Purpose :
1847: * Inputs :
1848: * ------------------------------------------------------------
1849: */
1850: void
1851: trm_Reselect(struct trm_softc *sc)
1852: {
1853: const bus_space_handle_t ioh = sc->sc_iohandle;
1854: const bus_space_tag_t iot = sc->sc_iotag;
1855: struct trm_scsi_req_q *pSRB;
1856: struct trm_dcb *pDCB;
1857: u_int16_t RselTarLunId;
1858: u_int8_t target, lun;
1859:
1860: #ifdef TRM_DEBUG0
1861: printf("%s: trm_Reselect\n", sc->sc_device.dv_xname);
1862: #endif
1863:
1864: pDCB = sc->pActiveDCB;
1865: if (pDCB != NULL) {
1866: /*
1867: * Arbitration lost but Reselection win
1868: */
1869: pSRB = pDCB->pActiveSRB;
1870: trm_RewaitSRB(sc, pSRB);
1871: }
1872:
1873: /*
1874: * Read Reselected Target Id and LUN
1875: */
1876: RselTarLunId = bus_space_read_2(iot, ioh, TRM_S1040_SCSI_TARGETID) & 0x1FFF;
1877: /* TODO XXXX: Make endian independent! */
1878: target = RselTarLunId & 0xff;
1879: lun = (RselTarLunId >> 8) & 0xff;
1880:
1881: #ifdef TRM_DEBUG0
1882: printf("%s: reselect - target = %d, lun = %d\n",
1883: sc->sc_device.dv_xname, target, lun);
1884: #endif
1885:
1886: if ((target < TRM_MAX_TARGETS) && (lun < TRM_MAX_LUNS))
1887: pDCB = sc->pDCB[target][lun];
1888: else
1889: pDCB = NULL;
1890:
1891: if (pDCB == NULL)
1892: printf("%s: reselect - target = %d, lun = %d not found\n",
1893: sc->sc_device.dv_xname, target, lun);
1894:
1895: sc->pActiveDCB = pDCB;
1896:
1897: /* TODO XXXX: This will crash if pDCB is ever NULL */
1898: if ((pDCB->DCBFlag & TRM_USE_TAG_QUEUING) != 0) {
1899: pSRB = &sc->SRB[0];
1900: pDCB->pActiveSRB = pSRB;
1901: } else {
1902: pSRB = pDCB->pActiveSRB;
1903: if (pSRB == NULL || (pSRB->SRBState != TRM_DISCONNECTED)) {
1904: /*
1905: * abort command
1906: */
1907: pSRB = &sc->SRB[0];
1908: pSRB->SRBState = TRM_UNEXPECT_RESEL;
1909: pDCB->pActiveSRB = pSRB;
1910: trm_EnableMsgOut(sc, MSG_ABORT);
1911: } else
1912: pSRB->SRBState = TRM_DATA_XFER;
1913: }
1914: pSRB->ScsiPhase = PH_BUS_FREE; /* SCSI bus free Phase */
1915:
1916: /*
1917: * Program HA ID, target ID, period and offset
1918: */
1919: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_TARGETID, target);
1920: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_HOSTID, sc->sc_AdaptSCSIID);
1921: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_SYNC, pDCB->SyncPeriod);
1922: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_OFFSET, pDCB->SyncOffset);
1923:
1924: /*
1925: * it's important for atn stop
1926: */
1927: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
1928: DELAY(30);
1929:
1930: /*
1931: * SCSI command
1932: * to rls the /ACK signal
1933: */
1934: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_COMMAND, SCMD_MSGACCEPT);
1935: }
1936:
1937: /*
1938: * ------------------------------------------------------------
1939: * Function : trm_FinishSRB
1940: * Purpose : Complete execution of a SCSI command
1941: * Signal completion to the generic SCSI driver
1942: * Inputs :
1943: * ------------------------------------------------------------
1944: */
1945: void
1946: trm_FinishSRB(struct trm_softc *sc, struct trm_scsi_req_q *pSRB)
1947: {
1948: struct scsi_inquiry_data *ptr;
1949: struct scsi_sense_data *s1, *s2;
1950: struct scsi_xfer *xs = pSRB->xs;
1951: struct trm_dcb *pDCB = pSRB->pSRBDCB;
1952: int target, lun;
1953:
1954: #ifdef TRM_DEBUG0
1955: printf("%s: trm_FinishSRB. sc = %p, pSRB = %p\n",
1956: sc->sc_device.dv_xname, sc, pSRB);
1957: #endif
1958: pDCB->DCBFlag &= ~TRM_QUEUE_FULL;
1959:
1960: if (xs == NULL) {
1961: trm_ReleaseSRB(sc, pSRB);
1962: return;
1963: }
1964:
1965: timeout_del(&xs->stimeout);
1966:
1967: xs->status = pSRB->TargetStatus;
1968:
1969: switch (xs->status) {
1970: case SCSI_INTERM_COND_MET:
1971: case SCSI_COND_MET:
1972: case SCSI_INTERM:
1973: case SCSI_OK:
1974: switch (pSRB->AdaptStatus) {
1975: case TRM_STATUS_GOOD:
1976: if ((pSRB->SRBFlag & TRM_PARITY_ERROR) != 0) {
1977: #ifdef TRM_DEBUG0
1978: printf("%s: trm_FinishSRB. TRM_PARITY_ERROR\n",
1979: sc->sc_device.dv_xname);
1980: #endif
1981: xs->error = XS_DRIVER_STUFFUP;
1982:
1983: } else if ((pSRB->SRBFlag & TRM_SCSI_TIMED_OUT) != 0) {
1984: xs->error = XS_TIMEOUT;
1985:
1986: } else if ((pSRB->SRBFlag & TRM_AUTO_REQSENSE) != 0) {
1987: s1 = &pSRB->scsisense;
1988: s2 = &xs->sense;
1989:
1990: *s2 = *s1;
1991:
1992: xs->status = SCSI_CHECK;
1993: xs->error = XS_SENSE;
1994:
1995: } else
1996: xs->error = XS_NOERROR;
1997: break;
1998:
1999: case TRM_OVER_UNDER_RUN:
2000: #ifdef TRM_DEBUG0
2001: printf("%s: trm_FinishSRB. TRM_OVER_UNDER_RUN\n",
2002: sc->sc_device.dv_xname);
2003: #endif
2004: xs->error = XS_DRIVER_STUFFUP;
2005: break;
2006:
2007: default:
2008: #ifdef TRM_DEBUG0
2009: printf("%s: trm_FinishSRB. AdaptStatus Error = 0x%02x\n",
2010: sc->sc_device.dv_xname, pSRB->AdaptStatus);
2011: #endif
2012: xs->error = XS_DRIVER_STUFFUP;
2013: break;
2014: }
2015: break;
2016:
2017: case SCSI_TERMINATED:
2018: case SCSI_ACA_ACTIVE:
2019: case SCSI_CHECK:
2020: if ((pSRB->SRBFlag & TRM_AUTO_REQSENSE) != 0)
2021: xs->error = XS_DRIVER_STUFFUP;
2022: else {
2023: trm_RequestSense(sc, pSRB);
2024: return;
2025: }
2026: break;
2027:
2028: case SCSI_QUEUE_FULL:
2029: /* this says no more until someone completes */
2030: pDCB->DCBFlag |= TRM_QUEUE_FULL;
2031: trm_RewaitSRB(sc, pSRB);
2032: return;
2033:
2034: case SCSI_RESV_CONFLICT:
2035: case SCSI_BUSY:
2036: xs->error = XS_BUSY;
2037: break;
2038:
2039: case TRM_SCSI_UNEXP_BUS_FREE:
2040: xs->status = SCSI_OK;
2041: xs->error = XS_DRIVER_STUFFUP;
2042: break;
2043:
2044: case TRM_SCSI_BUS_RST_DETECTED:
2045: xs->status = SCSI_OK;
2046: xs->error = XS_RESET;
2047: break;
2048:
2049: case TRM_SCSI_SELECT_TIMEOUT:
2050: xs->status = SCSI_OK;
2051: xs->error = XS_SELTIMEOUT;
2052: break;
2053:
2054: default:
2055: xs->error = XS_DRIVER_STUFFUP;
2056: break;
2057: }
2058:
2059: target = xs->sc_link->target;
2060: lun = xs->sc_link->lun;
2061:
2062: if ((xs->flags & SCSI_POLL) != 0) {
2063:
2064: if (xs->cmd->opcode == INQUIRY) {
2065:
2066: ptr = (struct scsi_inquiry_data *) xs->data;
2067:
2068: if ((xs->error != XS_NOERROR) ||
2069: ((ptr->device & SID_QUAL_BAD_LU) == SID_QUAL_BAD_LU)) {
2070: #ifdef TRM_DEBUG0
2071: printf("%s: trm_FinishSRB NO Device:target= %d,lun= %d\n",
2072: sc->sc_device.dv_xname, target, lun);
2073: #endif
2074: free(pDCB, M_DEVBUF);
2075: sc->pDCB[target][lun] = NULL;
2076: pDCB = NULL;
2077:
2078: } else
2079: pDCB->sc_link = xs->sc_link;
2080: }
2081: }
2082:
2083: trm_ReleaseSRB(sc, pSRB);
2084:
2085: xs->flags |= ITSDONE;
2086:
2087: /*
2088: * Notify cmd done
2089: */
2090: #ifdef TRM_DEBUG0
2091: if ((xs->error != 0) || (xs->status != 0) || ((xs->flags & SCSI_POLL) != 0))
2092: printf("%s: trm_FinishSRB. %d/%d xs->cmd->opcode = 0x%02x, xs->error = %d, xs->status = %d\n",
2093: sc->sc_device.dv_xname, target, lun, xs->cmd->opcode, xs->error, xs->status);
2094: #endif
2095:
2096: scsi_done(xs);
2097: }
2098:
2099: /*
2100: * ------------------------------------------------------------
2101: * Function : trm_ReleaseSRB
2102: * Purpose :
2103: * Inputs :
2104: * ------------------------------------------------------------
2105: */
2106: void
2107: trm_ReleaseSRB(struct trm_softc *sc, struct trm_scsi_req_q *pSRB)
2108: {
2109: struct scsi_xfer *xs = pSRB->xs;
2110: int intflag;
2111:
2112: intflag = splbio();
2113:
2114: if (pSRB->TagNumber != TRM_NO_TAG) {
2115: pSRB->pSRBDCB->TagMask &= ~(1 << pSRB->TagNumber);
2116: pSRB->TagNumber = TRM_NO_TAG;
2117: }
2118:
2119: if (xs != NULL) {
2120: timeout_del(&xs->stimeout);
2121:
2122: if (xs->datalen != 0) {
2123: bus_dmamap_sync(sc->sc_dmatag, pSRB->dmamapxfer,
2124: 0, pSRB->dmamapxfer->dm_mapsize,
2125: (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
2126: BUS_DMASYNC_POSTWRITE);
2127: bus_dmamap_unload(sc->sc_dmatag, pSRB->dmamapxfer);
2128: }
2129: }
2130:
2131: /* SRB may have started & finished, or be waiting and timed out */
2132: if ((pSRB->SRBFlag & TRM_ON_WAITING_SRB) != 0) {
2133: pSRB->SRBFlag &= ~TRM_ON_WAITING_SRB;
2134: TAILQ_REMOVE(&sc->waitingSRB, pSRB, link);
2135: }
2136: if ((pSRB->SRBFlag & TRM_ON_GOING_SRB) != 0) {
2137: pSRB->SRBFlag &= ~TRM_ON_GOING_SRB;
2138: TAILQ_REMOVE(&sc->goingSRB, pSRB, link);
2139: }
2140:
2141: bzero(&pSRB->SegmentX[0], sizeof(pSRB->SegmentX));
2142: bzero(&pSRB->CmdBlock[0], sizeof(pSRB->CmdBlock));
2143: bzero(&pSRB->scsisense, sizeof(pSRB->scsisense));
2144:
2145: pSRB->SRBTotalXferLength = 0;
2146: pSRB->SRBSGCount = 0;
2147: pSRB->SRBSGIndex = 0;
2148: pSRB->SRBFlag = 0;
2149:
2150: pSRB->SRBState = TRM_FREE;
2151: pSRB->AdaptStatus = TRM_STATUS_GOOD;
2152: pSRB->TargetStatus = SCSI_OK;
2153: pSRB->ScsiPhase = PH_BUS_FREE; /* SCSI bus free Phase */
2154:
2155: pSRB->xs = NULL;
2156: pSRB->pSRBDCB = NULL;
2157:
2158: if (pSRB != &sc->SRB[0])
2159: TAILQ_INSERT_TAIL(&sc->freeSRB, pSRB, link);
2160:
2161: splx(intflag);
2162: }
2163:
2164: /*
2165: * ------------------------------------------------------------
2166: * Function : trm_GoingSRB_Done
2167: * Purpose :
2168: * Inputs :
2169: * ------------------------------------------------------------
2170: */
2171: void
2172: trm_GoingSRB_Done(struct trm_softc *sc)
2173: {
2174: struct trm_scsi_req_q *pSRB;
2175:
2176: /* ASSUME we are inside a splbio()/splx() pair */
2177:
2178: while ((pSRB = TAILQ_FIRST(&sc->goingSRB)) != NULL) {
2179: /* TODO XXXX: Is TIMED_OUT the best status? */
2180: pSRB->SRBFlag |= TRM_SCSI_TIMED_OUT;
2181: trm_FinishSRB(sc, pSRB);
2182: }
2183: }
2184:
2185: /*
2186: * ------------------------------------------------------------
2187: * Function : trm_ResetSCSIBus
2188: * Purpose : Reset the SCSI bus
2189: * Inputs : struct trm_softc * -
2190: * ------------------------------------------------------------
2191: */
2192: void
2193: trm_ResetSCSIBus(struct trm_softc *sc)
2194: {
2195: const bus_space_handle_t ioh = sc->sc_iohandle;
2196: const bus_space_tag_t iot = sc->sc_iotag;
2197: int intflag;
2198:
2199: intflag = splbio();
2200:
2201: sc->sc_Flag |= RESET_DEV;
2202:
2203: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_RSTSCSI);
2204: while ((bus_space_read_2(iot, ioh,
2205: TRM_S1040_SCSI_INTSTATUS) & INT_SCSIRESET) == 0);
2206:
2207: splx(intflag);
2208: }
2209:
2210: /*
2211: * ------------------------------------------------------------
2212: * Function : trm_ScsiRstDetect
2213: * Purpose :
2214: * Inputs :
2215: * ------------------------------------------------------------
2216: */
2217: void
2218: trm_ScsiRstDetect(struct trm_softc *sc)
2219: {
2220: const bus_space_handle_t ioh = sc->sc_iohandle;
2221: const bus_space_tag_t iot = sc->sc_iotag;
2222: int wlval;
2223:
2224: #ifdef TRM_DEBUG0
2225: printf("%s: trm_ScsiRstDetect\n", sc->sc_device.dv_xname);
2226: #endif
2227:
2228: wlval = 1000;
2229: /*
2230: * delay 1 sec
2231: */
2232: while (--wlval != 0)
2233: DELAY(1000);
2234:
2235: bus_space_write_1(iot, ioh, TRM_S1040_DMA_CONTROL, STOPDMAXFER);
2236: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_CLRFIFO);
2237:
2238: if ((sc->sc_Flag & RESET_DEV) != 0)
2239: sc->sc_Flag |= RESET_DONE;
2240: else {
2241: sc->sc_Flag |= RESET_DETECT;
2242: trm_ResetAllDevParam(sc);
2243: trm_RecoverSRB(sc);
2244: sc->pActiveDCB = NULL;
2245: sc->sc_Flag = 0;
2246: trm_StartWaitingSRB(sc);
2247: }
2248: }
2249:
2250: /*
2251: * ------------------------------------------------------------
2252: * Function : trm_RequestSense
2253: * Purpose :
2254: * Inputs :
2255: * ------------------------------------------------------------
2256: */
2257: void
2258: trm_RequestSense(struct trm_softc *sc, struct trm_scsi_req_q *pSRB)
2259: {
2260: pSRB->SRBFlag |= TRM_AUTO_REQSENSE;
2261:
2262: /*
2263: * Status of initiator/target
2264: */
2265: pSRB->AdaptStatus = TRM_STATUS_GOOD;
2266: pSRB->TargetStatus = SCSI_OK;
2267: /*
2268: * Status of initiator/target
2269: */
2270:
2271: pSRB->SegmentX[0].address = pSRB->scsisensePhyAddr;
2272: pSRB->SegmentX[0].length = sizeof(struct scsi_sense_data);
2273: pSRB->SRBTotalXferLength = sizeof(struct scsi_sense_data);
2274: pSRB->SRBSGCount = 1;
2275: pSRB->SRBSGIndex = 0;
2276:
2277: bzero(&pSRB->CmdBlock[0], sizeof(pSRB->CmdBlock));
2278:
2279: pSRB->CmdBlock[0] = REQUEST_SENSE;
2280: pSRB->CmdBlock[1] = (pSRB->xs->sc_link->lun) << 5;
2281: pSRB->CmdBlock[4] = sizeof(struct scsi_sense_data);
2282:
2283: pSRB->ScsiCmdLen = 6;
2284:
2285: if ((pSRB->xs != NULL) && ((pSRB->xs->flags & SCSI_POLL) == 0))
2286: timeout_add(&pSRB->xs->stimeout, (pSRB->xs->timeout/1000) * hz);
2287:
2288: if (trm_StartSRB(sc, pSRB) != 0)
2289: trm_RewaitSRB(sc, pSRB);
2290: }
2291:
2292: /*
2293: * ------------------------------------------------------------
2294: * Function : trm_EnableMsgOut
2295: * Purpose : set up MsgBuf to send out a single byte message
2296: * Inputs :
2297: * ------------------------------------------------------------
2298: */
2299: void
2300: trm_EnableMsgOut(struct trm_softc *sc, u_int8_t msg)
2301: {
2302: sc->MsgBuf[0] = msg;
2303: sc->MsgCnt = 1;
2304:
2305: bus_space_write_2(sc->sc_iotag, sc->sc_iohandle, TRM_S1040_SCSI_CONTROL, DO_SETATN);
2306: }
2307:
2308: /*
2309: * ------------------------------------------------------------
2310: * Function : trm_linkSRB
2311: * Purpose :
2312: * Inputs :
2313: * ------------------------------------------------------------
2314: */
2315: void
2316: trm_linkSRB(struct trm_softc *sc)
2317: {
2318: struct trm_scsi_req_q *pSRB;
2319: int i, intflag;
2320:
2321: intflag = splbio();
2322:
2323: for (i = 0; i < TRM_MAX_SRB_CNT; i++) {
2324: pSRB = &sc->SRB[i];
2325:
2326: pSRB->PhysSRB = sc->sc_dmamap_control->dm_segs[0].ds_addr
2327: + i * sizeof(struct trm_scsi_req_q);
2328:
2329: pSRB->SRBSGPhyAddr = sc->sc_dmamap_control->dm_segs[0].ds_addr
2330: + i * sizeof(struct trm_scsi_req_q)
2331: + offsetof(struct trm_scsi_req_q, SegmentX);
2332:
2333: pSRB->scsisensePhyAddr = sc->sc_dmamap_control->dm_segs[0].ds_addr
2334: + i * sizeof(struct trm_scsi_req_q)
2335: + offsetof(struct trm_scsi_req_q, scsisense);
2336:
2337: /*
2338: * map all SRB space
2339: */
2340: if (bus_dmamap_create(sc->sc_dmatag, TRM_MAX_PHYSG_BYTE,
2341: TRM_MAX_SG_LISTENTRY, TRM_MAX_PHYSG_BYTE, 0,
2342: BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
2343: &pSRB->dmamapxfer) != 0) {
2344: printf("%s: unable to create DMA transfer map\n",
2345: sc->sc_device.dv_xname);
2346: splx(intflag);
2347: return;
2348: }
2349:
2350: if (i > 0)
2351: /* We use sc->SRB[0] directly, so *don't* link it */
2352: TAILQ_INSERT_TAIL(&sc->freeSRB, pSRB, link);
2353: #ifdef TRM_DEBUG0
2354: printf("pSRB = %p ", pSRB);
2355: #endif
2356: }
2357: #ifdef TRM_DEBUG0
2358: printf("\n ");
2359: #endif
2360: splx(intflag);
2361: }
2362:
2363: /*
2364: * ------------------------------------------------------------
2365: * Function : trm_minphys
2366: * Purpose : limited by the number of segments in the dma segment list
2367: * Inputs : *buf
2368: * ------------------------------------------------------------
2369: */
2370: void
2371: trm_minphys(struct buf *bp)
2372: {
2373: if (bp->b_bcount > (TRM_MAX_SG_LISTENTRY-1) * (long) NBPG) {
2374: bp->b_bcount = (TRM_MAX_SG_LISTENTRY-1) * (long) NBPG;
2375: }
2376: minphys(bp);
2377: }
2378:
2379: /*
2380: * ------------------------------------------------------------
2381: * Function : trm_initACB
2382: * Purpose : initialize the internal structures for a given SCSI host
2383: * Inputs :
2384: * ------------------------------------------------------------
2385: */
2386: void
2387: trm_initACB(struct trm_softc *sc, int unit)
2388: {
2389: const bus_space_handle_t ioh = sc->sc_iohandle;
2390: const bus_space_tag_t iot = sc->sc_iotag;
2391: struct trm_adapter_nvram *pEEpromBuf;
2392: struct trm_dcb *pDCB;
2393: int target, lun;
2394:
2395: pEEpromBuf = &trm_eepromBuf[unit];
2396: sc->sc_config = HCC_AUTOTERM | HCC_PARITY;
2397:
2398: if ((bus_space_read_1(iot, ioh, TRM_S1040_GEN_STATUS) & WIDESCSI) != 0)
2399: sc->sc_config |= HCC_WIDE_CARD;
2400:
2401: if ((pEEpromBuf->NvramChannelCfg & NAC_POWERON_SCSI_RESET) != 0)
2402: sc->sc_config |= HCC_SCSI_RESET;
2403:
2404: TAILQ_INIT(&sc->freeSRB);
2405: TAILQ_INIT(&sc->waitingSRB);
2406: TAILQ_INIT(&sc->goingSRB);
2407:
2408: sc->pActiveDCB = NULL;
2409: sc->sc_AdapterUnit = unit;
2410: sc->sc_AdaptSCSIID = pEEpromBuf->NvramScsiId;
2411: sc->sc_TagMaxNum = 2 << pEEpromBuf->NvramMaxTag;
2412: sc->sc_Flag = 0;
2413:
2414: /*
2415: * put all SRB's (except [0]) onto the freeSRB list
2416: */
2417: trm_linkSRB(sc);
2418:
2419: /*
2420: * allocate DCB array
2421: */
2422: for (target = 0; target < TRM_MAX_TARGETS; target++) {
2423: if (target == sc->sc_AdaptSCSIID)
2424: continue;
2425:
2426: for (lun = 0; lun < TRM_MAX_LUNS; lun++) {
2427: pDCB = (struct trm_dcb *)malloc(sizeof(struct trm_dcb), M_DEVBUF, M_NOWAIT);
2428: sc->pDCB[target][lun] = pDCB;
2429:
2430: if (pDCB == NULL)
2431: continue;
2432:
2433: bzero(pDCB, sizeof(struct trm_dcb));
2434:
2435: pDCB->target = target;
2436: pDCB->lun = lun;
2437: pDCB->pActiveSRB = NULL;
2438: }
2439: }
2440:
2441: sc->sc_adapter.scsi_cmd = trm_scsi_cmd;
2442: sc->sc_adapter.scsi_minphys = trm_minphys;
2443:
2444: sc->sc_link.adapter_softc = sc;
2445: sc->sc_link.adapter_target = sc->sc_AdaptSCSIID;
2446: sc->sc_link.openings = 30; /* So TagMask (32 bit integer) always has space */
2447: sc->sc_link.device = &trm_device;
2448: sc->sc_link.adapter = &sc->sc_adapter;
2449: sc->sc_link.adapter_buswidth = ((sc->sc_config & HCC_WIDE_CARD) == 0) ? 8:16;
2450:
2451: trm_reset(sc);
2452: }
2453:
2454: /*
2455: * ------------------------------------------------------------
2456: * Function : trm_write_all
2457: * Description : write pEEpromBuf 128 bytes to seeprom
2458: * Input : iot, ioh - chip's base address
2459: * Output : none
2460: * ------------------------------------------------------------
2461: */
2462: void
2463: trm_write_all(struct trm_adapter_nvram *pEEpromBuf, bus_space_tag_t iot,
2464: bus_space_handle_t ioh)
2465: {
2466: u_int8_t *bpEeprom = (u_int8_t *)pEEpromBuf;
2467: u_int8_t bAddr;
2468:
2469: /*
2470: * Enable SEEPROM
2471: */
2472: bus_space_write_1(iot, ioh, TRM_S1040_GEN_CONTROL,
2473: (bus_space_read_1(iot, ioh, TRM_S1040_GEN_CONTROL) | EN_EEPROM));
2474: /*
2475: * Write enable
2476: */
2477: trm_write_cmd(iot, ioh, 0x04, 0xFF);
2478: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, 0);
2479: trm_wait_30us(iot, ioh);
2480: for (bAddr = 0; bAddr < 128; bAddr++, bpEeprom++)
2481: trm_set_data(iot, ioh, bAddr, *bpEeprom);
2482: /*
2483: * Write disable
2484: */
2485: trm_write_cmd(iot, ioh, 0x04, 0x00);
2486: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, 0);
2487: trm_wait_30us(iot, ioh);
2488: /*
2489: * Disable SEEPROM
2490: */
2491: bus_space_write_1(iot, ioh, TRM_S1040_GEN_CONTROL,
2492: (bus_space_read_1(iot, ioh, TRM_S1040_GEN_CONTROL) & ~EN_EEPROM));
2493: }
2494:
2495: /*
2496: * ------------------------------------------------------------
2497: * Function : trm_set_data
2498: * Description : write one byte to seeprom
2499: * Input : iot, ioh - chip's base address
2500: * bAddr - address of SEEPROM
2501: * bData - data of SEEPROM
2502: * Output : none
2503: * ------------------------------------------------------------
2504: */
2505: void
2506: trm_set_data(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t bAddr,
2507: u_int8_t bData)
2508: {
2509: u_int8_t bSendData;
2510: int i;
2511:
2512: /*
2513: * Send write command & address
2514: */
2515: trm_write_cmd(iot, ioh, 0x05, bAddr);
2516: /*
2517: * Write data
2518: */
2519: for (i = 0; i < 8; i++, bData <<= 1) {
2520: bSendData = NVR_SELECT;
2521: if ((bData & 0x80) != 0) { /* Start from bit 7 */
2522: bSendData |= NVR_BITOUT;
2523: }
2524: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, bSendData);
2525: trm_wait_30us(iot, ioh);
2526: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM,
2527: (bSendData | NVR_CLOCK));
2528: trm_wait_30us(iot, ioh);
2529: }
2530: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, NVR_SELECT);
2531: trm_wait_30us(iot, ioh);
2532: /*
2533: * Disable chip select
2534: */
2535: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, 0);
2536: trm_wait_30us(iot, ioh);
2537: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, NVR_SELECT);
2538: trm_wait_30us(iot, ioh);
2539: /*
2540: * Wait for write ready
2541: */
2542: for (;;) {
2543: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM,
2544: (NVR_SELECT | NVR_CLOCK));
2545: trm_wait_30us(iot, ioh);
2546: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, NVR_SELECT);
2547: trm_wait_30us(iot, ioh);
2548: if (bus_space_read_1(iot, ioh, TRM_S1040_GEN_NVRAM) & NVR_BITIN)
2549: break;
2550: }
2551: /*
2552: * Disable chip select
2553: */
2554: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, 0);
2555: }
2556:
2557: /*
2558: * ------------------------------------------------------------
2559: * Function : trm_read_all
2560: * Description : read seeprom 128 bytes to pEEpromBuf
2561: * Input : pEEpromBuf, iot, ioh - chip's base address
2562: * Output : none
2563: * ------------------------------------------------------------
2564: */
2565: void
2566: trm_read_all(struct trm_adapter_nvram *pEEpromBuf, bus_space_tag_t iot,
2567: bus_space_handle_t ioh)
2568: {
2569: u_int8_t *bpEeprom = (u_int8_t *)pEEpromBuf;
2570: u_int8_t bAddr;
2571:
2572: /*
2573: * Enable SEEPROM
2574: */
2575: bus_space_write_1(iot, ioh, TRM_S1040_GEN_CONTROL,
2576: (bus_space_read_1(iot, ioh, TRM_S1040_GEN_CONTROL) | EN_EEPROM));
2577:
2578: for (bAddr = 0; bAddr < 128; bAddr++, bpEeprom++)
2579: *bpEeprom = trm_get_data(iot, ioh, bAddr);
2580:
2581: /*
2582: * Disable SEEPROM
2583: */
2584: bus_space_write_1(iot, ioh, TRM_S1040_GEN_CONTROL,
2585: (bus_space_read_1(iot, ioh, TRM_S1040_GEN_CONTROL) & ~EN_EEPROM));
2586: }
2587:
2588: /*
2589: * ------------------------------------------------------------
2590: * Function : trm_get_data
2591: * Description : read one byte from seeprom
2592: * Input : iot, ioh - chip's base address
2593: * bAddr - address of SEEPROM
2594: * Output : bData - data of SEEPROM
2595: * ------------------------------------------------------------
2596: */
2597: u_int8_t
2598: trm_get_data( bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t bAddr)
2599: {
2600: u_int8_t bReadData, bData;
2601: int i;
2602:
2603: bData = 0;
2604:
2605: /*
2606: * Send read command & address
2607: */
2608: trm_write_cmd(iot, ioh, 0x06, bAddr);
2609:
2610: for (i = 0; i < 8; i++) {
2611: /*
2612: * Read data
2613: */
2614: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM,
2615: (NVR_SELECT | NVR_CLOCK));
2616: trm_wait_30us(iot, ioh);
2617: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, NVR_SELECT);
2618: /*
2619: * Get data bit while falling edge
2620: */
2621: bReadData = bus_space_read_1(iot, ioh, TRM_S1040_GEN_NVRAM);
2622: bData <<= 1;
2623: if ((bReadData & NVR_BITIN) != 0)
2624: bData |= 1;
2625: trm_wait_30us(iot, ioh);
2626: }
2627: /*
2628: * Disable chip select
2629: */
2630: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, 0);
2631:
2632: return bData;
2633: }
2634:
2635: /*
2636: * ------------------------------------------------------------
2637: * Function : trm_wait_30us
2638: * Description : wait 30 us
2639: * Input : iot, ioh - chip's base address
2640: * Output : none
2641: * ------------------------------------------------------------
2642: */
2643: void
2644: trm_wait_30us(bus_space_tag_t iot, bus_space_handle_t ioh)
2645: {
2646: bus_space_write_1(iot, ioh, TRM_S1040_GEN_TIMER, 5);
2647:
2648: while ((bus_space_read_1(iot, ioh, TRM_S1040_GEN_STATUS) & GTIMEOUT)
2649: == 0);
2650: }
2651:
2652: /*
2653: * ------------------------------------------------------------
2654: * Function : trm_write_cmd
2655: * Description : write SB and Op Code into seeprom
2656: * Input : iot, ioh - chip's base address
2657: * bCmd - SB + Op Code
2658: * bAddr - address of SEEPROM
2659: * Output : none
2660: * ------------------------------------------------------------
2661: */
2662: void
2663: trm_write_cmd( bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t bCmd,
2664: u_int8_t bAddr)
2665: {
2666: u_int8_t bSendData;
2667: int i;
2668:
2669: for (i = 0; i < 3; i++, bCmd <<= 1) {
2670: /*
2671: * Program SB + OP code
2672: */
2673: bSendData = NVR_SELECT;
2674: if (bCmd & 0x04) /* Start from bit 2 */
2675: bSendData |= NVR_BITOUT;
2676: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, bSendData);
2677: trm_wait_30us(iot, ioh);
2678: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM,
2679: (bSendData | NVR_CLOCK));
2680: trm_wait_30us(iot, ioh);
2681: }
2682:
2683: for (i = 0; i < 7; i++, bAddr <<= 1) {
2684: /*
2685: * Program address
2686: */
2687: bSendData = NVR_SELECT;
2688: if (bAddr & 0x40) { /* Start from bit 6 */
2689: bSendData |= NVR_BITOUT;
2690: }
2691: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, bSendData);
2692: trm_wait_30us(iot, ioh);
2693: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM,
2694: (bSendData | NVR_CLOCK));
2695: trm_wait_30us(iot, ioh);
2696: }
2697: bus_space_write_1(iot, ioh, TRM_S1040_GEN_NVRAM, NVR_SELECT);
2698: trm_wait_30us(iot, ioh);
2699: }
2700:
2701: /*
2702: * ------------------------------------------------------------
2703: * Function : trm_check_eeprom
2704: * Description : read eeprom 128 bytes to pEEpromBuf and check
2705: * checksum. If it is wrong, updated with default value.
2706: * Input : eeprom, iot, ioh - chip's base address
2707: * Output : none
2708: * ------------------------------------------------------------
2709: */
2710: void
2711: trm_check_eeprom(struct trm_adapter_nvram *pEEpromBuf, bus_space_tag_t iot,
2712: bus_space_handle_t ioh)
2713: {
2714: u_int32_t *dpEeprom = (u_int32_t *)pEEpromBuf->NvramTarget;
2715: u_int32_t dAddr;
2716: u_int16_t *wpEeprom = (u_int16_t *)pEEpromBuf;
2717: u_int16_t wAddr, wCheckSum;
2718:
2719: #ifdef TRM_DEBUG0
2720: printf("\ntrm_check_eeprom\n");
2721: #endif
2722: trm_read_all(pEEpromBuf, iot, ioh);
2723: wCheckSum = 0;
2724: for (wAddr = 0; wAddr < 64; wAddr++, wpEeprom++)
2725: wCheckSum += *wpEeprom;
2726:
2727: if (wCheckSum != 0x1234) {
2728: #ifdef TRM_DEBUG0
2729: printf("TRM_S1040 EEPROM Check Sum ERROR (load default)\n");
2730: #endif
2731: /*
2732: * Checksum error, load default
2733: */
2734: pEEpromBuf->NvramSubVendorID[0] = (u_int8_t)PCI_VENDOR_TEKRAM2;
2735: pEEpromBuf->NvramSubVendorID[1] = (u_int8_t)(PCI_VENDOR_TEKRAM2
2736: >> 8);
2737: pEEpromBuf->NvramSubSysID[0] = (u_int8_t)
2738: PCI_PRODUCT_TEKRAM2_DC3X5U;
2739: pEEpromBuf->NvramSubSysID[1] = (u_int8_t)
2740: (PCI_PRODUCT_TEKRAM2_DC3X5U >> 8);
2741: pEEpromBuf->NvramSubClass = 0;
2742: pEEpromBuf->NvramVendorID[0] = (u_int8_t)PCI_VENDOR_TEKRAM2;
2743: pEEpromBuf->NvramVendorID[1] = (u_int8_t)(PCI_VENDOR_TEKRAM2
2744: >> 8);
2745: pEEpromBuf->NvramDeviceID[0] = (u_int8_t)
2746: PCI_PRODUCT_TEKRAM2_DC3X5U;
2747: pEEpromBuf->NvramDeviceID[1] = (u_int8_t)
2748: (PCI_PRODUCT_TEKRAM2_DC3X5U >> 8);
2749: pEEpromBuf->NvramReserved = 0;
2750:
2751: for (dAddr = 0; dAddr < 16; dAddr++, dpEeprom++)
2752: /*
2753: * NvmTarCfg3,NvmTarCfg2,NvmTarPeriod,NvmTarCfg0
2754: */
2755: *dpEeprom = 0x00000077;
2756:
2757: /*
2758: * NvramMaxTag,NvramDelayTime,NvramChannelCfg,NvramScsiId
2759: */
2760: *dpEeprom++ = 0x04000F07;
2761:
2762: /*
2763: * NvramReserved1,NvramBootLun,NvramBootTarget,NvramReserved0
2764: */
2765: *dpEeprom++ = 0x00000015;
2766: for (dAddr = 0; dAddr < 12; dAddr++, dpEeprom++)
2767: *dpEeprom = 0;
2768:
2769: pEEpromBuf->NvramCheckSum = 0;
2770: for (wAddr = 0, wCheckSum =0; wAddr < 63; wAddr++, wpEeprom++)
2771: wCheckSum += *wpEeprom;
2772:
2773: *wpEeprom = 0x1234 - wCheckSum;
2774: trm_write_all(pEEpromBuf, iot, ioh);
2775: }
2776: }
2777:
2778: /*
2779: * ------------------------------------------------------------
2780: * Function : trm_initAdapter
2781: * Purpose : initialize the SCSI chip ctrl registers
2782: * Inputs : psh - pointer to this host adapter's structure
2783: * ------------------------------------------------------------
2784: */
2785: void
2786: trm_initAdapter(struct trm_softc *sc)
2787: {
2788: const bus_space_handle_t ioh = sc->sc_iohandle;
2789: const bus_space_tag_t iot = sc->sc_iotag;
2790: u_int16_t wval;
2791: u_int8_t bval;
2792:
2793: /*
2794: * program configuration 0
2795: */
2796: if ((sc->sc_config & HCC_PARITY) != 0) {
2797: bval = PHASELATCH | INITIATOR | BLOCKRST | PARITYCHECK;
2798: } else {
2799: bval = PHASELATCH | INITIATOR | BLOCKRST;
2800: }
2801: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_CONFIG0, bval);
2802: /*
2803: * program configuration 1
2804: */
2805: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_CONFIG1, 0x13);
2806: /*
2807: * 250ms selection timeout
2808: */
2809: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_TIMEOUT, TRM_SEL_TIMEOUT);
2810: /*
2811: * Mask all the interrupt
2812: */
2813: bus_space_write_1(iot, ioh, TRM_S1040_DMA_INTEN, 0);
2814: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_INTEN, 0);
2815: /*
2816: * Reset SCSI module
2817: */
2818: bus_space_write_2(iot, ioh, TRM_S1040_SCSI_CONTROL, DO_RSTMODULE);
2819: /*
2820: * program Host ID
2821: */
2822: bval = sc->sc_AdaptSCSIID;
2823: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_HOSTID, bval);
2824: /*
2825: * set ansynchronous transfer
2826: */
2827: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_OFFSET, 0);
2828: /*
2829: * Turn LED control off
2830: */
2831: wval = bus_space_read_2(iot, ioh, TRM_S1040_GEN_CONTROL) & 0x7F;
2832: bus_space_write_2(iot, ioh, TRM_S1040_GEN_CONTROL, wval);
2833: /*
2834: * DMA config
2835: */
2836: wval = bus_space_read_2(iot, ioh, TRM_S1040_DMA_CONFIG) | DMA_ENHANCE;
2837: bus_space_write_2(iot, ioh, TRM_S1040_DMA_CONFIG, wval);
2838: /*
2839: * Clear pending interrupt status
2840: */
2841: bus_space_read_1(iot, ioh, TRM_S1040_SCSI_INTSTATUS);
2842: /*
2843: * Enable SCSI interrupts
2844: */
2845: bus_space_write_1(iot, ioh, TRM_S1040_SCSI_INTEN,
2846: (EN_SELECT | EN_SELTIMEOUT | EN_DISCONNECT | EN_RESELECTED |
2847: EN_SCSIRESET | EN_BUSSERVICE | EN_CMDDONE));
2848: bus_space_write_1(iot, ioh, TRM_S1040_DMA_INTEN, EN_SCSIINTR);
2849: }
2850:
2851: /*
2852: * ------------------------------------------------------------
2853: * Function : trm_init
2854: * Purpose : initialize the internal structures for a given SCSI host
2855: * Inputs : host - pointer to this host adapter's structure
2856: * Preconditions : when this function is called, the chip_type field of
2857: * the ACB structure MUST have been set.
2858: * ------------------------------------------------------------
2859: */
2860: int
2861: trm_init(struct trm_softc *sc, int unit)
2862: {
2863: const bus_space_handle_t ioh = sc->sc_iohandle;
2864: const bus_space_tag_t iot = sc->sc_iotag;
2865: bus_dma_segment_t seg;
2866: int error, rseg, all_srbs_size;
2867:
2868: /*
2869: * EEPROM CHECKSUM
2870: */
2871: trm_check_eeprom(&trm_eepromBuf[unit], iot, ioh);
2872:
2873: /*
2874: * MEMORY ALLOCATE FOR ADAPTER CONTROL BLOCK
2875: */
2876: /*
2877: * allocate the space for all SCSI control blocks (SRB) for DMA memory.
2878: */
2879: all_srbs_size = TRM_MAX_SRB_CNT * sizeof(struct trm_scsi_req_q);
2880:
2881: error = bus_dmamem_alloc(sc->sc_dmatag, all_srbs_size, NBPG, 0, &seg,
2882: 1, &rseg, BUS_DMA_NOWAIT);
2883: if (error != 0) {
2884: printf("%s: unable to allocate SCSI REQUEST BLOCKS, error = %d\n",
2885: sc->sc_device.dv_xname, error);
2886: /*errx(error, "%s: unable to allocate SCSI request blocks",
2887: sc->sc_device.dv_xname);*/
2888: return -1;
2889: }
2890:
2891: error = bus_dmamem_map(sc->sc_dmatag, &seg, rseg, all_srbs_size,
2892: (caddr_t *)&sc->SRB, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
2893: if (error != 0) {
2894: printf("%s: unable to map SCSI REQUEST BLOCKS, error = %d\n",
2895: sc->sc_device.dv_xname, error);
2896: /*errx(error, "unable to map SCSI request blocks");*/
2897: return -1;
2898: }
2899:
2900: error = bus_dmamap_create(sc->sc_dmatag, all_srbs_size, 1,
2901: all_srbs_size, 0, BUS_DMA_NOWAIT,&sc->sc_dmamap_control);
2902: if (error != 0) {
2903: printf("%s: unable to create SRB DMA maps, error = %d\n",
2904: sc->sc_device.dv_xname, error);
2905: /*errx(error, "unable to create SRB DMA maps");*/
2906: return -1;
2907: }
2908:
2909: error = bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap_control,
2910: sc->SRB, all_srbs_size, NULL, BUS_DMA_NOWAIT);
2911: if (error != 0) {
2912: printf("%s: unable to load SRB DMA maps, error = %d\n",
2913: sc->sc_device.dv_xname, error);
2914: /*errx(error, "unable to load SRB DMA maps");*/
2915: return -1;
2916: }
2917: #ifdef TRM_DEBUG0
2918: printf("\n\n%s: all_srbs_size=%x\n",
2919: sc->sc_device.dv_xname, all_srbs_size);
2920: #endif
2921: bzero(sc->SRB, all_srbs_size);
2922: trm_initACB(sc, unit);
2923: trm_initAdapter(sc);
2924:
2925: return 0;
2926: }
2927:
2928: /* ------------------------------------------------------------
2929: * Function : trm_print_info
2930: * Purpose : Print the DCB negotiation information
2931: * Inputs :
2932: * ------------------------------------------------------------
2933: */
2934: void
2935: trm_print_info(struct trm_softc *sc, struct trm_dcb *pDCB)
2936: {
2937: int syncXfer, index;
2938:
2939: index = pDCB->SyncPeriod & ~(WIDE_SYNC | ALT_SYNC);
2940:
2941: printf("%s: target %d using ", sc->sc_device.dv_xname, pDCB->target);
2942: if ((pDCB->SyncPeriod & WIDE_SYNC) != 0)
2943: printf("16 bit ");
2944: else
2945: printf("8 bit ");
2946:
2947: if (pDCB->SyncOffset == 0)
2948: printf("Asynchronous ");
2949: else {
2950: syncXfer = 100000 / (trm_clock_period[index] * 4);
2951: printf("%d.%01d MHz, Offset %d ",
2952: syncXfer / 100, syncXfer % 100, pDCB->SyncOffset);
2953: }
2954: printf("data transfers ");
2955:
2956: if ((pDCB->DCBFlag & TRM_USE_TAG_QUEUING) != 0)
2957: printf("with Tag Queuing");
2958:
2959: printf("\n");
2960: }
CVSweb