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