FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/bs/bs.c
1 /* $NecBSD: bs.c,v 1.1 1997/07/18 09:18:59 kmatsuda Exp $ */
2 /* $NetBSD$ */
3 /* $FreeBSD$ */
4 /*
5 * [NetBSD for NEC PC98 series]
6 * Copyright (c) 1994, 1995, 1996 NetBSD/pc98 porting staff.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32 /*
33 * Copyright (c) 1994, 1995, 1996 Naofumi HONDA. All rights reserved.
34 */
35
36 #ifdef __NetBSD__
37 #include <i386/Cbus/dev/bs/bsif.h>
38 #endif
39 #ifdef __FreeBSD__
40 #include <i386/isa/bs/bsif.h>
41 #endif
42
43 #include <cam/cam.h>
44 #include <cam/cam_ccb.h>
45 #include <cam/cam_sim.h>
46 #include <cam/cam_xpt_sim.h>
47 #include <cam/cam_debug.h>
48
49 #include <cam/scsi/scsi_all.h>
50 #include <cam/scsi/scsi_message.h>
51
52 /*****************************************************************
53 * Inline phase funcs
54 *****************************************************************/
55 /* static inline declare */
56 static BS_INLINE struct targ_info *bs_reselect __P((struct bs_softc *));
57 static BS_INLINE void bs_sat_continue __P((struct bs_softc *, struct targ_info *, struct bsccb *));
58 static BS_INLINE struct targ_info *bs_selected __P((struct bs_softc *, struct targ_info *, struct bsccb *));
59 static BS_INLINE u_int8_t bs_read_1byte __P((struct bs_softc *));
60 static BS_INLINE void bs_write_1byte __P((struct bs_softc *, u_int8_t));
61 static BS_INLINE void bs_commandout __P((struct bs_softc *, struct targ_info *, struct bsccb *));
62 static BS_INLINE void bs_status_check __P((struct bs_softc *, struct targ_info *));
63 static BS_INLINE void bs_msgin __P((struct bs_softc *, struct targ_info *));
64 static BS_INLINE void bs_msgout __P((struct bs_softc *, struct targ_info *, struct bsccb *));
65 static BS_INLINE void bs_disconnect_phase __P((struct bs_softc *, struct targ_info *, struct bsccb *));
66 static void bs_phase_error __P((struct targ_info *, struct bsccb *));
67 static int bs_scsi_cmd_poll_internal __P((struct targ_info *));
68 static int bs_xfer __P((struct bs_softc *, char *, int));
69 static void bs_io_xfer __P((struct targ_info *));
70 static void bs_quick_abort __P((struct targ_info *, u_int));
71 static void bs_msgin_error __P((struct targ_info *, u_int));
72 static void bs_msgin_ext __P((struct targ_info *));
73 static void bs_msg_reject __P((struct targ_info *));
74 static void bshoststart __P((struct bs_softc *, struct targ_info *));
75
76 /*****************************************************************
77 * SIM interface
78 *****************************************************************/
79 void
80 bs_scsi_cmd(struct cam_sim *sim, union ccb *ccb)
81 {
82 struct bs_softc *bsc = (struct bs_softc *) cam_sim_softc(sim);
83 int s, target = (u_int) (ccb->ccb_h.target_id);
84 struct targ_info *ti;
85 struct bsccb *cb;
86
87 switch (ccb->ccb_h.func_code) {
88 case XPT_SCSI_IO: /* Execute the requested I/O operation */
89 ti = bsc->sc_ti[target];
90 if ((cb = bs_get_ccb()) == NULL) {
91 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
92 xpt_done(ccb);
93 return;
94 }
95
96 /* make up ccb! */
97 cb->ccb = ccb;
98 cb->lun = ccb->ccb_h.target_lun;
99 cb->cmd = ccb->csio.cdb_io.cdb_bytes;
100 cb->cmdlen = (int) ccb->csio.cdb_len;
101 cb->data = ccb->csio.data_ptr;
102 cb->datalen = (int) ccb->csio.dxfer_len;
103 cb->rcnt = 0;
104 cb->msgoutlen = 0;
105 cb->bsccb_flags = 0;
106 bs_targ_flags(ti, cb);
107 cb->tcmax = 0;/*(xs->timeout >> 10); default HN2*/
108 if (cb->tcmax < BS_DEFAULT_TIMEOUT_SECOND)
109 cb->tcmax = BS_DEFAULT_TIMEOUT_SECOND;
110
111 s = splcam();
112
113 TAILQ_INSERT_TAIL(&ti->ti_ctab, cb, ccb_chain);
114
115 if (ti->ti_phase == FREE) {
116 if (ti->ti_state == BS_TARG_START)
117 bs_start_syncmsg(ti, NULL, BS_SYNCMSG_ASSERT);
118 bscmdstart(ti, BSCMDSTART);
119 }
120
121 splx(s);
122 break;
123 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
124 case XPT_EN_LUN: /* Enable LUN as a target */
125 case XPT_TARGET_IO: /* Execute target I/O request */
126 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
127 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
128 case XPT_ABORT: /* Abort the specified CCB */
129 /* XXX Implement */
130 ccb->ccb_h.status = CAM_REQ_INVALID;
131 xpt_done(ccb);
132 break;
133 case XPT_SET_TRAN_SETTINGS:
134 /* XXX Implement */
135 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
136 xpt_done(ccb);
137 break;
138 case XPT_GET_TRAN_SETTINGS: {
139 struct ccb_trans_settings *cts;
140 struct targ_info *ti;
141 /*int s;*/
142
143 cts = &ccb->cts;
144 ti = bsc->sc_ti[ccb->ccb_h.target_id];
145 /*s = splcam();*/
146 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) {
147 if (ti->ti_cfgflags & BS_SCSI_DISC)
148 cts->flags = CCB_TRANS_DISC_ENB;
149 else
150 cts->flags = 0;
151 if (ti->ti_cfgflags & BS_SCSI_QTAG)
152 cts->flags |= CCB_TRANS_TAG_ENB;
153 cts->sync_period = ti->ti_syncnow.period;
154 cts->sync_offset = ti->ti_syncnow.offset;
155 cts->bus_width = 0;/*HN2*/
156
157 cts->valid = CCB_TRANS_SYNC_RATE_VALID
158 | CCB_TRANS_SYNC_OFFSET_VALID
159 | CCB_TRANS_BUS_WIDTH_VALID
160 | CCB_TRANS_DISC_VALID
161 | CCB_TRANS_TQ_VALID;
162 ccb->ccb_h.status = CAM_REQ_CMP;
163 } else
164 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
165
166 /*splx(s);*/
167 xpt_done(ccb);
168 break;
169 }
170 case XPT_CALC_GEOMETRY: { /* not yet HN2 */
171 struct ccb_calc_geometry *ccg;
172 u_int32_t size_mb;
173 u_int32_t secs_per_cylinder;
174
175 ccg = &ccb->ccg;
176 size_mb = ccg->volume_size
177 / ((1024L * 1024L) / ccg->block_size);
178
179 ccg->heads = 8;
180 ccg->secs_per_track = 34;
181
182 secs_per_cylinder = ccg->heads * ccg->secs_per_track;
183 ccg->cylinders = ccg->volume_size / secs_per_cylinder;
184 ccb->ccb_h.status = CAM_REQ_CMP;
185 xpt_done(ccb);
186 break;
187 }
188 case XPT_RESET_BUS: /* Reset the specified SCSI bus */
189 bshw_chip_reset(bsc); /* XXX need perfect RESET? */
190 ccb->ccb_h.status = CAM_REQ_CMP;
191 xpt_done(ccb);
192 break;
193 case XPT_TERM_IO: /* Terminate the I/O process */
194 /* XXX Implement */
195 ccb->ccb_h.status = CAM_REQ_INVALID;
196 xpt_done(ccb);
197 break;
198 case XPT_PATH_INQ: { /* Path routing inquiry */
199 struct ccb_pathinq *cpi = &ccb->cpi;
200
201 cpi->version_num = 1; /* XXX??? */
202 cpi->hba_inquiry = PI_SDTR_ABLE;
203 cpi->target_sprt = 0;
204 cpi->hba_misc = 0;
205 cpi->hba_eng_cnt = 0;
206 cpi->max_target = NTARGETS - 1;
207 cpi->max_lun = 7;
208 cpi->initiator_id = bsc->sc_hostid;
209 cpi->bus_id = cam_sim_bus(sim);
210 cpi->base_transfer_speed = 3300;
211 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
212 strncpy(cpi->hba_vid, "NEC", HBA_IDLEN);
213 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
214 cpi->unit_number = cam_sim_unit(sim);
215 cpi->ccb_h.status = CAM_REQ_CMP;
216 xpt_done(ccb);
217 break;
218 }
219 default:
220 /*printf("bs: non support func_code = %d ", ccb->ccb_h.func_code);*/
221 ccb->ccb_h.status = CAM_REQ_INVALID;
222 xpt_done(ccb);
223 break;
224 }
225 }
226
227 /**************************************************
228 * ### NEXUS START and TERMINATE ###
229 **************************************************/
230 /*
231 * FLAGS : BSCMDRESTART restart in case of error.
232 */
233 int
234 bscmdstart(ti, flags)
235 struct targ_info *ti;
236 int flags;
237 {
238 struct bsccb *cb;
239 struct bs_softc *bsc = ti->ti_bsc;
240
241 if ((cb = ti->ti_ctab.tqh_first) == NULL)
242 {
243 if (bsc->sc_nexus == NULL)
244 bshoststart(bsc, NULL);
245 return 0;
246 }
247
248 ti->ti_lun = cb->lun;
249 ti->ti_error = 0;
250 ti->ti_scsp.data = cb->data;
251 ti->ti_scsp.datalen = cb->datalen;
252 ti->ti_scsp.seglen = 0;
253 if (cb->rcnt)
254 cb->bsccb_flags &= ~(BSSAT | BSLINK);
255 ti->ti_flags &= ~BSCFLAGSMASK;
256 ti->ti_flags |= cb->bsccb_flags & BSCFLAGSMASK;
257 cb->tc = cb->tcmax;
258
259 /* GO GO */
260 if (ti->ti_phase == FREE)
261 {
262 if (bsc->sc_nexus == NULL)
263 bshoststart(bsc, ti);
264 else
265 {
266 if (flags & BSCMDRESTART)
267 bs_hostque_head(bsc, ti);
268 else
269 bs_hostque_tail(bsc, ti);
270 BS_SETUP_PHASE(HOSTQUEUE)
271 }
272 }
273 else if (bsc->sc_nexus == NULL)
274 bshoststart(bsc, NULL);
275
276 return 1;
277 }
278
279 struct bsccb *
280 bscmddone(ti)
281 struct targ_info *ti;
282 {
283 struct bs_softc *bsc = ti->ti_bsc;
284 struct bsccb *cb = ti->ti_ctab.tqh_first;
285 union ccb *ccb;
286 int error;
287
288 if (ti->ti_state == BS_TARG_SYNCH)
289 {
290 if (bs_analyze_syncmsg(ti, cb))
291 return cb;
292 }
293
294 if (bsc->sc_p.datalen != 0)
295 ti->ti_error |= BSDMAABNORMAL;
296
297 cb->error = ti->ti_error;
298
299 do
300 {
301 ccb = cb->ccb;
302 error = CAM_REQ_CMP;
303
304 if (cb->bsccb_flags & (BSITSDONE | BSSENSECCB | BSCASTAT))
305 {
306 if (cb->bsccb_flags & BSSENSECCB)
307 {
308 cb->error &= ~BSDMAABNORMAL;
309 if (cb->error == 0)
310 ti->ti_flags |= BSCASTAT;
311
312 ti->ti_flags |= BSERROROK;
313 }
314 else if (cb->bsccb_flags & BSCASTAT)
315 {
316 if (ti->ti_flags & BSCASTAT)
317 {
318 ti->ti_flags &= ~BSCASTAT;
319 error = CAM_AUTOSNS_VALID|CAM_SCSI_STATUS_ERROR;
320 if (ccb)
321 ccb->csio.sense_data = ti->sense;/* XXX may not be csio.... */
322 }
323 else
324 error = CAM_AUTOSENSE_FAIL;
325 ti->ti_flags |= BSERROROK;
326 } else
327 bs_panic(bsc, "internal error");
328 }
329
330 while (cb->error)
331 {
332 if (ti->ti_flags & BSERROROK)
333 break;
334
335 if (cb->rcnt >= bsc->sc_retry || (cb->error & BSFATALIO))
336 {
337 if (cb->error & (BSSELTIMEOUT | BSTIMEOUT))
338 error = CAM_CMD_TIMEOUT;
339 else if (cb->error & BSTARGETBUSY)
340 error = CAM_SCSI_STATUS_ERROR;
341 else
342 error = CAM_REQ_CMP_ERR;
343 break;
344 }
345
346 if (cb->error & BSREQSENSE)
347 {
348 /* must clear the target's sense state */
349 cb->rcnt++;
350 cb->bsccb_flags |= (BSITSDONE | BSCASTAT);
351 cb->error &= ~BSREQSENSE;
352 return bs_request_sense(ti);
353 }
354
355 /* XXX: compat with upper driver */
356 if ((cb->error & BSDMAABNORMAL) &&
357 BSHW_CMD_CHECK(cb, BSERROROK))
358 {
359 cb->error &= ~BSDMAABNORMAL;
360 continue;
361 }
362 if (/*(xs && xs->bp) || can't know whether bufferd i/o or not */
363 (cb->error & BSSELTIMEOUT) == 0)
364 bs_debug_print(bsc, ti);
365 cb->rcnt++;
366 return cb;
367 }
368
369 #ifdef BS_DIAG
370 cb->bsccb_flags |= BSITSDONE;
371 #endif /* BS_DIAG */
372 if (bsc->sc_poll)
373 {
374 bsc->sc_flags |= BSJOBDONE;
375 if (bsc->sc_outccb == cb)
376 bsc->sc_flags |= BSPOLLDONE;
377 }
378
379 TAILQ_REMOVE(&ti->ti_ctab, cb, ccb_chain);
380
381 if (ccb)
382 {
383 ccb->ccb_h.status = error;
384 ccb->csio.scsi_status = ti->ti_status;/*XXX*/
385 xpt_done(ccb);
386 }
387
388 bs_free_ccb(cb);
389 cb = ti->ti_ctab.tqh_first;
390
391 }
392 while (cb != NULL && (cb->bsccb_flags & BSITSDONE) != 0);
393
394 /* complete */
395 return NULL;
396 }
397
398 /**************************************************
399 * ### PHASE FUNCTIONS ###
400 **************************************************/
401 /**************************************************
402 * <SELECTION PHASE>
403 **************************************************/
404 static void
405 bshoststart(bsc, ti)
406 struct bs_softc *bsc;
407 struct targ_info *ti;
408 {
409 struct bsccb *cb;
410 int s;
411
412 if (bsc->sc_flags & BSINACTIVE)
413 return;
414
415 again:
416 if (ti == NULL)
417 {
418 if ((ti = bsc->sc_sttab.tqh_first) == NULL)
419 return;
420 bs_hostque_delete(bsc, ti);
421 }
422
423 if ((cb = ti->ti_ctab.tqh_first) == NULL)
424 {
425 bs_printf(ti, "bshoststart", "Warning: No ccb");
426 BS_SETUP_PHASE(FREE);
427 ti = NULL;
428 goto again;
429 }
430
431 #ifdef BS_DIAG
432 if (cb->bsccb_flags & BSITSDONE)
433 bs_panic(bsc, "bshoststart: already done");
434
435 if (bsc->sc_nexus || (ti->ti_flags & BSNEXUS))
436 {
437 char *s = ((ti->ti_flags & BSNEXUS) ?
438 "nexus already established" : "scsi board busy");
439
440 bs_debug_print(bsc, ti);
441 bs_printf(ti, "bshoststart", s);
442 }
443 #endif /* BS_DIAG */
444
445 #ifdef BS_STATICS
446 bs_statics[ti->ti_id].select++;
447 #endif /* BS_STATICS */
448
449 if (ti->ti_cfgflags & BS_SCSI_WAIT)
450 {
451 struct targ_info *tmpti;
452
453 for (tmpti = bsc->sc_titab.tqh_first; tmpti;
454 tmpti = tmpti->ti_tchain.tqe_next)
455 if (tmpti->ti_phase >= DISCONNECTED)
456 goto retry;
457 }
458
459 /* start selection */
460 ti->ti_status = ST_UNK;
461 if (bs_check_sat(ti))
462 {
463 if ((bshw_get_auxstat(bsc) & STR_BUSY) == 0)
464 {
465 BS_LOAD_SDP
466 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
467 bshw_setup_ctrl_reg(bsc, ti->ti_cfgflags);
468 bshw_cmd_pass(bsc, 0);
469 bshw_set_sync_reg(bsc, ti->ti_sync);
470 bshw_issue_satcmd(bsc, cb, bs_check_link(ti, cb));
471 if (bs_check_smit(ti) || bsc->sc_p.datalen <= 0)
472 bshw_set_count(bsc, 0);
473 else
474 bs_dma_xfer(ti, BSHW_CMD_CHECK(cb, BSREAD));
475
476 s = splhigh();
477 if ((bshw_get_auxstat(bsc) & STR_BUSY) == 0)
478 {
479 /* XXX:
480 * Reload a lun again here.
481 */
482 bshw_set_lun(bsc, ti->ti_lun);
483 bshw_start_sat(bsc, bs_check_disc(ti));
484 if ((bshw_get_auxstat(bsc) & STR_LCI) == 0)
485 {
486 splx(s);
487 BS_HOST_START
488 BS_SELECTION_START
489 BS_SETUP_PHASE(SATSEL);
490 ti->ti_omsgoutlen = 0;
491 ti->ti_msgout = bs_identify_msg(ti);
492 #ifdef BS_DIAG
493 ti->ti_flags |= BSNEXUS;
494 #endif /* BS_DIAG */
495 #ifdef BS_STATICS
496 bs_statics[ti->ti_id].select_win++;
497 #endif /* BS_STATICS */
498 return;
499 }
500 }
501 splx(s);
502
503 if (bs_check_smit(ti) == 0)
504 bshw_dmaabort(bsc, ti);
505 #ifdef BS_STATICS
506 bs_statics[ti->ti_id].select_miss_in_assert++;
507 #endif /* BS_STATICS */
508 }
509 }
510 else
511 {
512 s = splhigh();
513 if ((bshw_get_auxstat(bsc) & STR_BUSY) == 0)
514 {
515 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
516 bshw_setup_ctrl_reg(bsc, ti->ti_cfgflags);
517 bshw_set_sync_reg(bsc, ti->ti_sync);
518 bshw_assert_select(bsc);
519
520 if ((bshw_get_auxstat(bsc) & STR_LCI) == 0)
521 {
522 splx(s);
523 BS_HOST_START
524 BS_SELECTION_START
525 BS_SETUP_PHASE(SELECTASSERT);
526 #ifdef BS_STATICS
527 bs_statics[ti->ti_id].select_win++;
528 #endif /* BS_STATICS */
529 return;
530 }
531 #ifdef BS_STATICS
532 bs_statics[ti->ti_id].select_miss_in_assert++;
533 #endif /* BS_STATICS */
534 }
535 splx(s);
536 }
537
538 /* RETRY LATER */
539 retry:
540 #ifdef BS_STATICS
541 bs_statics[ti->ti_id].select_miss++;
542 #endif /* BS_STATICS */
543 bs_hostque_head(bsc, ti);
544 BS_SETUP_PHASE(HOSTQUEUE)
545 }
546
547 static BS_INLINE struct targ_info *
548 bs_selected(bsc, ti, cb)
549 struct bs_softc *bsc;
550 struct targ_info *ti;
551 struct bsccb *cb;
552 {
553
554 if (bsc->sc_busstat != BSR_SELECTED)
555 {
556 bs_phase_error(ti, cb);
557 return NULL;
558 }
559
560 #ifdef BS_DIAG
561 if (bsc->sc_selwait != ti)
562 panic("%s selection internal error\n", bsc->sc_dvname);
563
564 ti->ti_flags |= BSNEXUS;
565 #endif /* BS_DIAG */
566
567 /* clear select wait state */
568 BS_SETUP_PHASE(SELECTED);
569 BS_SELECTION_TERMINATE;
570 BS_LOAD_SDP
571 return ti;
572 }
573
574 /**************************************************
575 * <RESELECTION>
576 **************************************************/
577 static BS_INLINE struct targ_info *
578 bs_reselect(bsc)
579 struct bs_softc *bsc;
580 {
581 u_int target;
582 struct targ_info *ti;
583
584 /* check collision */
585 if ((ti = bsc->sc_selwait) != NULL)
586 {
587 if (ti->ti_phase == SATSEL)
588 {
589 #ifdef BS_DIAG
590 ti->ti_flags &= ~BSNEXUS;
591 #endif /* BS_DIAG */
592 ti->ti_msgout = 0;
593 if (bs_check_smit(ti) == 0)
594 bshw_dmaabort(bsc, ti);
595 }
596 bs_hostque_head(bsc, ti);
597 BS_SELECTION_TERMINATE
598 BS_SETUP_PHASE(HOSTQUEUE)
599 #ifdef BS_STATICS
600 bs_statics[ti->ti_id].select_miss_by_reselect++;
601 bs_statics[ti->ti_id].select_miss++;
602 #endif /* BS_STATICS */
603 }
604
605 /* who are you ? */
606 target = bshw_get_src_id(bsc);
607 if ((ti = bsc->sc_ti[target]) == NULL)
608 {
609 bs_debug_print_all(bsc);
610 printf("reselect: miss reselect. target(%d)\n", target);
611 bs_reset_nexus(bsc);
612 return NULL;
613 }
614
615 /* confirm nexus */
616 BS_HOST_START
617 bshw_setup_ctrl_reg(bsc, ti->ti_cfgflags);
618 if (ti->ti_ctab.tqh_first == NULL || ti->ti_phase != DISCONNECTED)
619 {
620 bs_printf(ti, "reselect", "phase mismatch");
621 BS_SETUP_PHASE(UNDEF)
622 bs_force_abort(ti);
623 bs_hostque_delete(bsc, ti);
624 }
625 else
626 bsc->sc_dtgnum --;
627
628 /* recover host */
629 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
630 bshw_set_sync_reg(bsc, ti->ti_sync);
631 BS_RESTORE_SDP
632 BS_SETUP_PHASE(RESELECTED)
633 #ifdef BS_STATICS
634 bs_statics[ti->ti_id].reselect++;
635 #endif /* BS_STATICS */
636 return ti;
637 }
638
639 static BS_INLINE void
640 bs_sat_continue(bsc, ti, cb)
641 struct bs_softc *bsc;
642 struct targ_info *ti;
643 struct bsccb *cb;
644 {
645
646 BS_SETUP_PHASE(SATRESEL);
647 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
648 bshw_cmd_pass(bsc, 0x44);
649 bshw_set_sync_reg(bsc, ti->ti_sync);
650 bshw_issue_satcmd(bsc, cb, 0);
651 if (bs_check_smit(ti) || bsc->sc_p.datalen <= 0)
652 bshw_set_count(bsc, 0);
653 else
654 bs_dma_xfer(ti, BSHW_CMD_CHECK(cb, BSREAD));
655 bshw_set_lun(bsc, ti->ti_lun); /* XXX */
656 bshw_start_sat(bsc, 0);
657 }
658
659 /*************************************************
660 * <DATA PHASE>
661 *************************************************/
662 #define DR (STR_BSY | STR_DBR)
663
664 void
665 bs_poll_timeout(bsc, s)
666 struct bs_softc *bsc;
667 char *s;
668 {
669 struct targ_info *ti;
670
671 bs_printf(NULL, s, "timeout");
672 bsc->sc_flags |= BSRESET;
673 if ((ti = bsc->sc_nexus) && ti->ti_ctab.tqh_first)
674 ti->ti_error |= BSTIMEOUT;
675 }
676
677 static BS_INLINE u_int8_t
678 bs_read_1byte(bsc)
679 struct bs_softc *bsc;
680 {
681 register u_int wc;
682
683 bshw_start_sxfer(bsc);
684 for (wc = bsc->sc_wc; (bshw_get_auxstat(bsc) & DR) != DR && --wc; );
685 if (wc)
686 return bshw_read_data(bsc);
687 else
688 bs_poll_timeout(bsc, "read_1byte");
689
690 return 0;
691 }
692
693 static BS_INLINE void
694 bs_write_1byte(bsc, data)
695 struct bs_softc *bsc;
696 u_int8_t data;
697 {
698 register u_int wc;
699
700 bshw_start_sxfer(bsc);
701 for (wc = bsc->sc_wc; (bshw_get_auxstat(bsc) & DR) != DR && --wc; );
702 if (wc)
703 bshw_write_data(bsc, data);
704 else
705 bs_poll_timeout(bsc, "write_1byte");
706 }
707
708 static int
709 bs_xfer(bsc, data, len)
710 struct bs_softc *bsc;
711 char *data;
712 int len;
713 {
714 u_int8_t aux;
715 u_int count, wc;
716
717 bshw_set_count(bsc, len);
718 bshw_start_xfer(bsc);
719
720 for (count = 0, wc = bsc->sc_wc; count < len && --wc; )
721 {
722 if (((aux = bshw_get_auxstat(bsc)) & DR) == DR)
723 {
724 if (bsc->sc_busstat & BSHW_READ)
725 *(data++) = bshw_read_data(bsc);
726 else
727 bshw_write_data(bsc, *(data++));
728 count++;
729 wc = bsc->sc_wc;
730 }
731
732 if (aux & STR_INT)
733 break;
734 }
735
736 if (wc == 0)
737 bs_poll_timeout(bsc, "bs_xfer");
738
739 return count;
740 }
741 #undef DR
742
743 static void
744 bs_io_xfer(ti)
745 struct targ_info *ti;
746 {
747 struct bs_softc *bsc = ti->ti_bsc;
748 struct sc_p *sp = &bsc->sc_p;
749 u_int count, dummy;
750
751 /* switch dma trasnfr mode */
752 bshw_set_poll_trans(bsc, ti->ti_cfgflags);
753 sp->seglen = 0;
754 sp->bufp = NULL;
755
756 if (sp->datalen <= 0)
757 {
758 ti->ti_error |= BSDMAABNORMAL;
759 dummy = 0;
760 count = bs_xfer(bsc, (u_int8_t *) &dummy, 1);
761 }
762 else
763 count = bs_xfer(bsc, sp->data, sp->datalen);
764
765 sp->data += count;
766 sp->datalen -= count;
767 }
768
769 /************************************************
770 * <COMMAND PHASE>
771 ************************************************/
772 static BS_INLINE void
773 bs_commandout(bsc, ti, cb)
774 struct bs_softc *bsc;
775 struct targ_info *ti;
776 struct bsccb *cb;
777 {
778 u_int8_t scsi_cmd[16];
779 int len;
780
781 BS_SETUP_PHASE(CMDPHASE);
782
783 if (bs_check_link(ti, cb))
784 {
785 bcopy(cb->cmd, scsi_cmd, cb->cmdlen);
786 scsi_cmd[cb->cmdlen - 1] |= 0x01;
787 len = bs_xfer(bsc, scsi_cmd, cb->cmdlen);
788 }
789 else
790 len = bs_xfer(bsc, cb->cmd, cb->cmdlen);
791
792 if (len != cb->cmdlen)
793 ti->ti_error |= BSCMDABNORMAL;
794 }
795
796 /************************************************
797 * <STATUS IN>
798 ************************************************/
799 static BS_INLINE void
800 bs_status_check(bsc, ti)
801 struct bs_softc *bsc;
802 struct targ_info *ti;
803 {
804
805 if (ti->ti_status == ST_GOOD || ti->ti_status == ST_INTERGOOD)
806 return;
807
808 switch (ti->ti_status)
809 {
810 case ST_MET:
811 case ST_INTERMET:
812 case ST_CHKCOND:
813 ti->ti_error |= BSREQSENSE;
814 break;
815
816 case ST_BUSY:
817 ti->ti_error |= BSTARGETBUSY;
818 break;
819
820 default:
821 ti->ti_error |= BSSTATUSERROR;
822 break;
823 }
824 }
825
826 /************************************************
827 * <MSG IN>
828 ************************************************/
829 #define MSGWAIT(cnt) { if (ti->ti_msginptr < (cnt)) return; }
830
831 static void
832 bs_quick_abort(ti, msg)
833 struct targ_info *ti;
834 u_int msg;
835 {
836 struct bsccb *cb;
837
838 if ((cb = ti->ti_ctab.tqh_first) == NULL)
839 return;
840
841 cb->msgoutlen = 1;
842 cb->msgout[0] = msg;
843 cb->rcnt++;
844
845 ti->ti_error |= BSMSGERROR;
846 }
847
848 static void
849 bs_msgin_error(ti, count)
850 struct targ_info *ti;
851 u_int count;
852 {
853 int n;
854
855 MSGWAIT(count);
856
857 bs_printf(ti, "msgin", "illegal msg");
858
859 for (n = 0; n < ti->ti_msginptr; n ++)
860 printf("[0x%x] ", (u_int) ti->ti_msgin[n]);
861 printf("\n");
862
863 bs_quick_abort(ti, MSG_REJECT);
864 ti->ti_msginptr = 0;
865 }
866
867 static void
868 bs_msgin_ext(ti)
869 struct targ_info *ti;
870 {
871 struct bs_softc *bsc = ti->ti_bsc;
872 struct bsccb *cb = ti->ti_ctab.tqh_first;
873 int count;
874 u_int reqlen;
875 u_int32_t *ptr;
876 struct msgbase msg;
877
878 MSGWAIT(2);
879
880 reqlen = ti->ti_msgin[1];
881 if (reqlen == 0)
882 reqlen = 256;
883
884 if (ti->ti_msginptr >= MAXMSGLEN)
885 ti->ti_msginptr = 3; /* XXX */
886
887 MSGWAIT(reqlen + 2);
888
889 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
890 {
891 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
892 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
893 count = (int) htonl((long) (*ptr));
894
895 bsc->sc_p.seglen = ti->ti_scsp.seglen = 0;
896 if (bsc->sc_p.datalen - count >= 0 &&
897 bsc->sc_p.datalen - count <= cb->datalen)
898 {
899 bsc->sc_p.datalen -= count;
900 bsc->sc_p.data += count;
901 }
902 else
903 bs_msgin_error(ti, 7);
904 break;
905
906 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
907 ti->ti_syncnow.period = ti->ti_msgin[3];
908 ti->ti_syncnow.offset = ti->ti_msgin[4];
909 if (ti->ti_syncnow.offset == 0)
910 ti->ti_syncnow.period = 0;
911
912 if (ti->ti_syncnow.state != BS_SYNCMSG_ASSERT)
913 {
914 bs_start_syncmsg(ti, NULL, BS_SYNCMSG_REQUESTED);
915 bscmdstart(ti, BSCMDSTART);
916 }
917 else
918 BS_SETUP_SYNCSTATE(BS_SYNCMSG_ACCEPT)
919 break;
920
921 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
922 msg.msglen = MSG_EXTEND_WIDELEN + 2;
923 msg.msg[0] = MSG_EXTEND;
924 msg.msg[1] = MSG_EXTEND_WIDELEN;
925 msg.msg[2] = MSG_EXTEND_WIDECODE;
926 msg.msg[3] = 0;
927 msg.flag = 0;
928 bs_make_msg_ccb(ti, cb->lun, cb, &msg, 0);
929 break;
930
931 default:
932 bs_msgin_error(ti, 0);
933 return;
934 }
935
936 ti->ti_msginptr = 0;
937 return;
938 }
939
940 static void
941 bs_msg_reject(ti)
942 struct targ_info *ti;
943 {
944 struct bs_softc *bsc = ti->ti_bsc;
945 struct bsccb *cb = ti->ti_ctab.tqh_first;
946 char *s = "unexpected msg reject";
947
948 switch (ti->ti_ophase)
949 {
950 case CMDPHASE:
951 s = "cmd rejected";
952 cb->bsccb_flags &= ~BSLINK;
953 BS_SETUP_MSGPHASE(IOCOMPLETED);
954 break;
955
956 case MSGOUT:
957 if (ti->ti_msgout & 0x80)
958 {
959 s = "identify msg rejected";
960 cb->bsccb_flags &= ~BSDISC;
961 BS_SETUP_MSGPHASE(IOCOMPLETED);
962 }
963 else if (ti->ti_msgout == MSG_EXTEND)
964 {
965 switch (ti->ti_emsgout)
966 {
967 case MSG_EXTEND_SYNCHCODE:
968 BS_SETUP_SYNCSTATE(BS_SYNCMSG_REJECT);
969 return;
970
971 default:
972 break;
973 }
974 }
975 break;
976
977 default:
978 break;
979 }
980
981 bs_debug_print(bsc, ti);
982 bs_printf(ti, "msgin", s);
983 ti->ti_error |= BSMSGERROR;
984 }
985
986 static BS_INLINE void
987 bs_msgin(bsc, ti)
988 struct bs_softc *bsc;
989 struct targ_info *ti;
990 {
991
992 BS_SETUP_PHASE(MSGIN);
993
994 switch (ti->ti_msgin[0])
995 {
996 case MSG_SAVESP:
997 BS_SAVE_SDP
998 break;
999
1000 case MSG_RESTORESP:
1001 BS_RESTORE_SDP
1002 bs_printf(ti, "msgin", "restore scsi pointer");
1003 break;
1004
1005 case MSG_REJECT:
1006 bs_msg_reject(ti);
1007 break;
1008
1009 case 0xf:
1010 break;
1011
1012 case MSG_I_ERROR:/* all I -> T : nothing to do*/
1013 case MSG_ABORT:
1014 case MSG_PARITY:
1015 case MSG_RESET:
1016 case 0xe:
1017 bs_msgin_error(ti, 1);
1018 goto resume;
1019
1020 case MSG_NOOP:
1021 break;
1022
1023 case MSG_EXTEND:
1024 bs_msgin_ext(ti);
1025 goto resume;
1026
1027 case 0xd:
1028 bs_msgin_error(ti, 2);
1029 goto resume;
1030
1031 case MSG_DISCON:
1032 BS_SETUP_MSGPHASE(DISCONNECTASSERT);
1033 break;
1034
1035 case MSG_COMP:
1036 BS_SETUP_MSGPHASE(IOCOMPLETED);
1037 break;
1038
1039 case MSG_LCOMP:
1040 case MSG_LCOMP_F:
1041 bs_status_check(bsc, ti);
1042 if (bscmddone(ti) == NULL)
1043 {
1044 if (bscmdstart(ti, BSCMDSTART) == 0)
1045 {
1046 bs_printf(ti, "msgin", "cmd line miss");
1047 bs_force_abort(ti);
1048 }
1049 }
1050 else
1051 bscmdstart(ti, BSCMDRESTART);
1052 #ifdef BS_STATICS
1053 bs_linkcmd_count[ti->ti_id]++;
1054 #endif /* BS_STATICS */
1055 BS_LOAD_SDP
1056 ti->ti_status = ST_UNK;
1057 break;
1058
1059 default:
1060 if (ti->ti_msgin[0] & 0x80)
1061 {
1062 if ((ti->ti_msgin[0] & 0x07) != ti->ti_lun)
1063 {
1064 ti->ti_lun = (ti->ti_msgin[0] & 0x07);
1065 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
1066 bshw_set_sync_reg(bsc, ti->ti_sync);
1067
1068 bs_printf(ti, "msgin", "lun error");
1069 bs_quick_abort(ti, MSG_ABORT);
1070 }
1071 break;
1072 }
1073 else if (ti->ti_msgin[0] < 0x20)
1074 bs_msgin_error(ti, 1);
1075 else if (ti->ti_msgin[0] < 0x30)
1076 bs_msgin_error(ti, 2);
1077 else
1078 bs_msgin_error(ti, 1);
1079 goto resume;
1080 }
1081
1082 ti->ti_msginptr = 0;
1083
1084 resume:
1085 return;
1086 }
1087
1088 /************************************************
1089 * <MSG OUT>
1090 ************************************************/
1091 static BS_INLINE void
1092 bs_msgout(bsc, ti, cb)
1093 struct bs_softc *bsc;
1094 struct targ_info *ti;
1095 struct bsccb *cb;
1096 {
1097 u_int8_t msg[MAXMSGLEN + 1];
1098
1099 if (ti->ti_phase == MSGOUT)
1100 {
1101 if (cb->rcnt ++ < bsc->sc_retry)
1102 cb->msgoutlen = ti->ti_omsgoutlen;
1103 }
1104 else
1105 BS_SETUP_PHASE(MSGOUT);
1106
1107 if (ti->ti_ophase == SELECTED)
1108 {
1109 identify:
1110 if (cb->msgoutlen == 0)
1111 {
1112 ti->ti_msgout = bs_identify_msg(ti);
1113 ti->ti_omsgoutlen = 0;
1114 bs_write_1byte(bsc, ti->ti_msgout);
1115 }
1116 else
1117 {
1118 if (cb->msgout[0] != MSG_RESET &&
1119 cb->msgout[0] != MSG_ABORT)
1120 {
1121 msg[0] = bs_identify_msg(ti);
1122 bcopy(cb->msgout, &msg[1], cb->msgoutlen);
1123 bs_xfer(bsc, msg, cb->msgoutlen + 1);
1124 }
1125 else
1126 bs_xfer(bsc, cb->msgout, cb->msgoutlen);
1127
1128 ti->ti_msgout = cb->msgout[0];
1129 ti->ti_emsgout = cb->msgout[2];
1130 ti->ti_omsgoutlen = cb->msgoutlen;
1131 cb->msgoutlen = 0;
1132 }
1133 return;
1134 }
1135
1136 if (ti->ti_ophase == SATSEL)
1137 {
1138 /* XXX:
1139 * Maybe identify msg rejected due to
1140 * a parity error in target side.
1141 */
1142
1143 bs_printf(ti, "msgout", "msg identify retry (SAT)");
1144 goto identify;
1145 }
1146
1147 if (cb->msgoutlen == 0)
1148 {
1149 ti->ti_msgout = MSG_REJECT;
1150 ti->ti_omsgoutlen = 0;
1151 bs_write_1byte(bsc, ti->ti_msgout);
1152 }
1153 else
1154 {
1155 ti->ti_msgout = cb->msgout[0];
1156 ti->ti_emsgout = cb->msgout[2];
1157 ti->ti_omsgoutlen = cb->msgoutlen;
1158 bs_xfer(bsc, cb->msgout, cb->msgoutlen);
1159 cb->msgoutlen = 0;
1160 }
1161 }
1162
1163 /************************************************
1164 * <DISCONNECT>
1165 ************************************************/
1166 static BS_INLINE void
1167 bs_disconnect_phase(bsc, ti, cb)
1168 struct bs_softc *bsc;
1169 struct targ_info *ti;
1170 struct bsccb *cb;
1171 {
1172
1173 switch (bsc->sc_msgphase)
1174 {
1175 default:
1176 panic("%s unknown msg phase\n", bsc->sc_dvname);
1177 break;
1178
1179 case DISCONNECTASSERT:
1180 case FREE:
1181 #ifdef BS_STATICS
1182 bs_statics[ti->ti_id].disconnected++;
1183 #endif /* BS_STATICS */
1184 if (ti->ti_cfgflags & BS_SCSI_SAVESP)
1185 BS_SAVE_SDP;
1186 BS_HOST_TERMINATE;
1187 BS_SETUP_PHASE(DISCONNECTED);
1188 bsc->sc_dtgnum ++;
1189 bshoststart(bsc, NULL);
1190 break;
1191
1192 case IOCOMPLETED:
1193 bs_status_check(bsc, ti);
1194 cb = bscmddone(ti);
1195 #ifdef BS_DIAG
1196 ti->ti_flags &= ~BSNEXUS;
1197 #endif /* BS_DIAG */
1198 BS_SETUP_PHASE(FREE);
1199 if (cb || bsc->sc_sttab.tqh_first == NULL)
1200 {
1201 BS_HOST_TERMINATE;
1202 bscmdstart(ti, BSCMDSTART);
1203 }
1204 else
1205 {
1206 /* give a chance to other target */
1207 bscmdstart(ti, BSCMDSTART);
1208 BS_HOST_TERMINATE;
1209 bshoststart(bsc, NULL);
1210 }
1211 break;
1212 }
1213
1214 BS_SETUP_MSGPHASE(FREE);
1215 }
1216
1217 /**************************************************
1218 * <PHASE ERROR>
1219 **************************************************/
1220 #define scsi_status (bsc->sc_busstat)
1221
1222 struct bs_err {
1223 u_char *pe_msg;
1224 u_int pe_err;
1225 u_int pe_ph;
1226 };
1227
1228 struct bs_err bs_cmderr[] = {
1229 /**/ { "illegal cmd", BSABNORMAL, UNDEF },
1230 /*1*/ { "unexpected bus free", BSABNORMAL, FREE },
1231 /*2*/ { NULL, BSSELTIMEOUT, FREE},
1232 /*3*/ { "scsi bus parity error", BSPARITY, UNDEF },
1233 /*4*/ { "scsi bus parity error", BSPARITY, UNDEF },
1234 /*5*/ { "unknown" , BSFATALIO, UNDEF },
1235 /*6*/ { "miss reselection (target mode)", BSFATALIO, UNDEF },
1236 /*7*/ { "wrong status byte", BSPARITY, STATUSIN },
1237 };
1238
1239 static void
1240 bs_phase_error(ti, cb)
1241 struct targ_info *ti;
1242 struct bsccb *cb;
1243 {
1244 struct bs_softc *bsc = ti->ti_bsc;
1245 struct bs_err *pep;
1246
1247 if ((scsi_status & BSR_CM) == BSR_CMDERR &&
1248 (scsi_status & BSR_PHVALID) == 0)
1249 {
1250 pep = &bs_cmderr[scsi_status & BSR_PM];
1251 ti->ti_error |= pep->pe_err;
1252 if (pep->pe_msg)
1253 {
1254 bs_debug_print(bsc, ti);
1255 bs_printf(ti, "bsintr", pep->pe_msg);
1256 }
1257 BS_SETUP_PHASE(pep->pe_ph);
1258 }
1259 else
1260 {
1261 ti->ti_error |= BSABNORMAL;
1262 bs_debug_print(bsc, ti);
1263 bs_printf(ti, "bsintr", "phase error");
1264 BS_SETUP_PHASE(UNDEF);
1265 }
1266
1267 BS_SETUP_MSGPHASE(FREE);
1268 switch (ti->ti_phase)
1269 {
1270 case FREE:
1271 BS_SETUP_PHASE(UNDEF);
1272 cb = bscmddone(ti);
1273 #ifdef BS_DIAG
1274 ti->ti_flags &= ~BSNEXUS;
1275 #endif /* BS_DIAG */
1276 BS_HOST_TERMINATE;
1277 BS_SETUP_PHASE(FREE);
1278 bscmdstart(ti, ((cb == NULL) ? BSCMDSTART : BSCMDRESTART));
1279 break;
1280
1281 case STATUSIN:
1282 ti->ti_error |= BSSTATUSERROR;
1283 ti->ti_status = bshw_get_status_insat(bsc); /* XXX SAT */
1284 bs_debug_print(bsc, ti);
1285 break;
1286
1287 case UNDEF:
1288 default:
1289 ti->ti_error |= BSABNORMAL;
1290 bs_reset_nexus(bsc);
1291 break;
1292 }
1293 }
1294
1295 /**************************************************
1296 * ### SCSI PHASE SEQUENCER ###
1297 **************************************************/
1298 static BS_INLINE void bs_ack_wait __P((struct bs_softc *, struct targ_info *, struct bsccb *));
1299
1300 static BS_INLINE void
1301 bs_ack_wait(bsc, ti, cb)
1302 struct bs_softc *bsc;
1303 struct targ_info *ti;
1304 struct bsccb *cb;
1305 {
1306 int wc = bsc->sc_wc;
1307
1308 for (wc = bsc->sc_wc; bshw_get_busstat(bsc) != BSR_ACKREQ && wc > 0; )
1309 wc --;
1310
1311 if (wc <= 0)
1312 {
1313 bs_printf(ti, "bs_ack_wait", "timeout I");
1314 return;
1315 }
1316
1317 bshw_get_auxstat(bsc);
1318 scsi_status = bshw_get_busstat(bsc);
1319
1320 if (cb->msgoutlen > 0)
1321 {
1322 bshw_assert_atn(bsc);
1323 delay(800);
1324 BS_SETUP_PHASE(ATTENTIONASSERT);
1325 }
1326
1327 bshw_negate_ack(bsc);
1328
1329 #ifdef WAITNEXTP
1330 for (wc = bsc->sc_wc; bshw_get_busstat(bsc) == BSR_ACKREQ && wc > 0; )
1331 wc --;
1332
1333 if (wc <= 0)
1334 bs_printf(ti, "bs_ack_wait", "timeout II");
1335 #endif /* WAITNEXTP */
1336 }
1337
1338 int
1339 bs_sequencer(bsc)
1340 struct bs_softc *bsc;
1341 {
1342 register struct targ_info *ti;
1343 struct bsccb *cb;
1344
1345 /**************************************************
1346 * Check reset
1347 **************************************************/
1348 if (bsc->sc_flags & (BSRESET | BSINACTIVE))
1349 {
1350 if (bsc->sc_flags & BSRESET)
1351 bs_reset_nexus(bsc);
1352 return 1;
1353 }
1354
1355 /**************************************************
1356 * Get status & bus phase
1357 **************************************************/
1358 if ((bshw_get_auxstat(bsc) & STR_INT) == 0)
1359 return 0;
1360
1361 scsi_status = bshw_get_busstat(bsc);
1362 if (scsi_status == ((u_int8_t) -1))
1363 {
1364 bs_debug_print_all(bsc);
1365 return 1;
1366 }
1367 /**************************************************
1368 * Check reselection, or nexus
1369 **************************************************/
1370 if (scsi_status == BSR_RESEL)
1371 {
1372 bs_reselect(bsc);
1373 return 1;
1374 }
1375
1376 ti = bsc->sc_nexus;
1377 if (ti == NULL || (cb = ti->ti_ctab.tqh_first) == NULL)
1378 {
1379 bs_debug_print_all(bsc);
1380 bs_printf(ti, "bsintr", "no nexus");
1381 bs_reset_nexus(bsc);
1382 return 1;
1383 }
1384
1385 /**************************************************
1386 * Debug section
1387 **************************************************/
1388 #ifdef BS_DEBUG
1389 if (bs_debug_flag)
1390 {
1391 bs_debug_print(bsc, ti);
1392 if (bs_debug_flag > 1)
1393 Debugger();
1394 }
1395 #endif /* BS_DEBUG */
1396
1397 /**************************************************
1398 * internal scsi phase
1399 **************************************************/
1400 switch (ti->ti_phase)
1401 {
1402 case SELECTASSERT:
1403 bs_selected(bsc, ti, cb);
1404 return 1;
1405
1406 case SATSEL:
1407 BS_SELECTION_TERMINATE;
1408
1409 case SATRESEL:
1410 if (bsc->sc_flags & (BSDMASTART | BSSMITSTART))
1411 {
1412 if (bsc->sc_flags & BSSMITSTART)
1413 {
1414 bs_debug_print_all(bsc);
1415 bs_reset_nexus(bsc);
1416 bs_printf(ti, "bsintr", "smit transfer");
1417 return 1;
1418 }
1419
1420 BS_SETUP_PHASE(DATAPHASE); /* XXX */
1421 bs_dma_xfer_end(ti);
1422 ti->ti_phase = ti->ti_ophase; /* XXX */
1423 }
1424 break;
1425
1426 default:
1427 /* XXX:
1428 * check check check for safety !!
1429 */
1430 if (bsc->sc_selwait)
1431 {
1432 /* Ghaaa! phase error! retry! */
1433 bs_phase_error(ti, cb);
1434 return 1;
1435 }
1436
1437 if (bsc->sc_flags & (BSDMASTART | BSSMITSTART))
1438 {
1439 if (bsc->sc_flags & BSDMASTART)
1440 bs_dma_xfer_end(ti);
1441 else
1442 bs_smit_xfer_end(ti);
1443 }
1444 break;
1445 }
1446
1447 /**************************************************
1448 * hw scsi phase
1449 **************************************************/
1450 if (scsi_status & BSR_PHVALID)
1451 {
1452 /**************************************************
1453 * Normal SCSI phase.
1454 **************************************************/
1455 if ((scsi_status & BSR_CM) == BSR_CMDABT)
1456 {
1457 bs_phase_error(ti, cb);
1458 return 1;
1459 }
1460
1461 switch (scsi_status & BSR_PM)
1462 {
1463 case BSR_DATAOUT:
1464 case BSR_DATAIN:
1465 BS_SETUP_PHASE(DATAPHASE);
1466
1467 if (bsc->sc_p.datalen <= 0 ||
1468 (ti->ti_flags & BSFORCEIOPOLL))
1469 {
1470 bs_io_xfer(ti);
1471 return 1;
1472 }
1473
1474 if (bs_check_smit(ti) &&
1475 (bsc->sc_p.datalen % sizeof(u_int32_t)) == 0)
1476 {
1477 bs_lc_smit_xfer(ti, scsi_status & BSR_IOR);
1478 return 1;
1479 }
1480
1481 bs_dma_xfer(ti, scsi_status & BSR_IOR);
1482 bshw_start_xfer(bsc);
1483 return 1;
1484
1485 case BSR_CMDOUT:
1486 bs_commandout(bsc, ti, cb);
1487 return 1;
1488
1489 case BSR_STATIN:
1490 if (bs_check_sat(ti))
1491 {
1492 BS_SETUP_PHASE(SATCOMPSEQ);
1493 bshw_set_count(bsc, 0);
1494 bshw_cmd_pass(bsc, 0x41);
1495 bshw_start_sat(bsc, 0);
1496 }
1497 else
1498 {
1499 BS_SETUP_PHASE(STATUSIN);
1500 ti->ti_status = bs_read_1byte(bsc);
1501 }
1502 return 1;
1503
1504 case BSR_UNSPINFO0:
1505 case BSR_UNSPINFO1:
1506 bs_debug_print(bsc, ti);
1507 bs_printf(ti, "bsintr", "illegal bus phase");
1508 return 1;
1509
1510 case BSR_MSGOUT:
1511 bs_msgout(bsc, ti, cb);
1512 return 1;
1513
1514 case BSR_MSGIN:/* msg in */
1515 if (bs_check_sat(ti))
1516 {
1517 if (ti->ti_phase == RESELECTED)
1518 {
1519 bs_sat_continue(bsc, ti, cb);
1520 return 1;
1521 }
1522 /* XXX */
1523 if (ti->ti_status == ST_UNK)
1524 ti->ti_status = bshw_get_status_insat(bsc);
1525 }
1526
1527 ti->ti_msgin[ti->ti_msginptr ++] = bs_read_1byte(bsc);
1528 bs_msgin(bsc, ti);
1529 if (bsc->sc_cfgflags & BSC_FASTACK)
1530 bs_ack_wait(bsc, ti, cb);
1531
1532 return 1;
1533 }
1534 }
1535 else
1536 {
1537 /**************************************************
1538 * Special SCSI phase
1539 **************************************************/
1540 switch (scsi_status)
1541 {
1542 case BSR_SATSDP:/* SAT with save data pointer */
1543 BS_SAVE_SDP
1544 bshw_cmd_pass(bsc, 0x41);
1545 bshw_start_sat(bsc, 0);
1546 BS_SETUP_PHASE(SATSDP)
1547 return 1;
1548
1549 case BSR_SATFIN:/* SAT COMPLETE */
1550 ti->ti_status = bshw_get_status_insat(bsc);
1551 BS_SETUP_MSGPHASE(IOCOMPLETED);
1552 bs_disconnect_phase(bsc, ti, cb);
1553 return 1;
1554
1555 case BSR_ACKREQ:/* negate ACK */
1556 if (cb->msgoutlen > 0)
1557 {
1558 bshw_assert_atn(bsc);
1559 delay(800);
1560 BS_SETUP_PHASE(ATTENTIONASSERT);
1561 }
1562 bshw_negate_ack(bsc);
1563 return 1;
1564
1565 case BSR_DISC:/* disconnect */
1566 bs_disconnect_phase(bsc, ti, cb);
1567 return 1;
1568
1569 default:
1570 break;
1571 }
1572 }
1573
1574 bs_phase_error(ti, cb);
1575 return 1;
1576 }
1577
1578 /*****************************************************************
1579 * INTERNAL POLLING FUNCTIONS
1580 *****************************************************************/
1581 static int
1582 bs_scsi_cmd_poll_internal(cti)
1583 struct targ_info *cti;
1584 {
1585 struct bs_softc *bsc = cti->ti_bsc;
1586 struct targ_info *ti;
1587 struct bsccb *cb;
1588 int i, waits, delay_count;
1589
1590 bsc->sc_poll++;
1591
1592 /* setup timeout count */
1593 if ((ti = bsc->sc_nexus) == NULL ||
1594 (cb = ti->ti_ctab.tqh_first) == NULL)
1595 waits = BS_DEFAULT_TIMEOUT_SECOND * 1000000;
1596 else
1597 waits = cb->tcmax * 1000000;
1598
1599 /* force all current jobs into the polling state. */
1600 for (i = 0; i < NTARGETS; i++)
1601 {
1602 if ((ti = bsc->sc_ti[i]) != NULL)
1603 {
1604 ti->ti_flags |= BSFORCEIOPOLL;
1605 if ((cb = ti->ti_ctab.tqh_first) != NULL)
1606 cb->bsccb_flags |= BSFORCEIOPOLL;
1607 }
1608 }
1609
1610 /* do io */
1611 bsc->sc_flags &= ~BSJOBDONE;
1612 do
1613 {
1614 delay_count = ((bsc->sc_flags & BSDMASTART) ? 1000000 : 100);
1615 delay(delay_count);
1616 waits -= delay_count;
1617 bs_sequencer(bsc);
1618 }
1619 while (waits >= 0 && (bsc->sc_flags & (BSUNDERRESET | BSJOBDONE)) == 0);
1620
1621 /* done */
1622 bsc->sc_poll--;
1623 if (waits < 0 || (bsc->sc_flags & BSUNDERRESET))
1624 {
1625 bs_printf(NULL, "cmd_poll", "timeout or fatal");
1626 return HASERROR;
1627 }
1628
1629 return COMPLETE;
1630 }
1631
1632 int
1633 bs_scsi_cmd_poll(cti, targetcb)
1634 struct targ_info *cti;
1635 struct bsccb *targetcb;
1636 {
1637 struct bs_softc *bsc = cti->ti_bsc;
1638 struct targ_info *ti;
1639 int s, error = COMPLETE;
1640
1641 s = splcam();
1642 bs_terminate_timeout(bsc);
1643
1644 if (bsc->sc_hstate == BSC_TARG_CHECK)
1645 {
1646 if ((error = bs_scsi_cmd_poll_internal(cti)) != COMPLETE)
1647 bs_reset_nexus(bsc);
1648 }
1649 else
1650 {
1651 if (bsc->sc_outccb)
1652 bs_panic(bsc, "bs_cmd_poll: internal error");
1653
1654 bsc->sc_flags &= ~BSPOLLDONE;
1655 bsc->sc_outccb = targetcb;
1656
1657 while ((bsc->sc_flags & BSPOLLDONE) == 0)
1658 {
1659 if (bs_scsi_cmd_poll_internal(cti) != COMPLETE)
1660 {
1661 if ((ti = bsc->sc_nexus) && ti->ti_ctab.tqh_first)
1662 ti->ti_error |= (BSTIMEOUT | BSABNORMAL);
1663 bs_reset_nexus(bsc);
1664 }
1665 }
1666
1667 bsc->sc_outccb = NULL;
1668 }
1669
1670 bs_start_timeout(bsc);
1671 softintr(bsc->sc_irq);
1672 splx(s);
1673 return error;
1674 }
Cache object: 5bcaa40455f3e91f6340b78de272df83
|