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