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: releng/5.0/sys/i386/isa/bs/bs.c 92765 2002-03-20 07:51:46Z alfred $ */
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(struct bs_softc *);
57 static BS_INLINE void bs_sat_continue(struct bs_softc *, struct targ_info *, struct bsccb *);
58 static BS_INLINE struct targ_info *bs_selected(struct bs_softc *, struct targ_info *, struct bsccb *);
59 static BS_INLINE u_int8_t bs_read_1byte(struct bs_softc *);
60 static BS_INLINE void bs_write_1byte(struct bs_softc *, u_int8_t);
61 static BS_INLINE void bs_commandout(struct bs_softc *, struct targ_info *, struct bsccb *);
62 static BS_INLINE void bs_status_check(struct bs_softc *, struct targ_info *);
63 static BS_INLINE void bs_msgin(struct bs_softc *, struct targ_info *);
64 static BS_INLINE void bs_msgout(struct bs_softc *, struct targ_info *, struct bsccb *);
65 static BS_INLINE void bs_disconnect_phase(struct bs_softc *, struct targ_info *, struct bsccb *);
66 static void bs_phase_error(struct targ_info *, struct bsccb *);
67 static int bs_scsi_cmd_poll_internal(struct targ_info *);
68 static int bs_xfer(struct bs_softc *, char *, int);
69 static void bs_io_xfer(struct targ_info *);
70 static void bs_quick_abort(struct targ_info *, u_int);
71 static void bs_msgin_error(struct targ_info *, u_int);
72 static void bs_msgin_ext(struct targ_info *);
73 static void bs_msg_reject(struct targ_info *);
74 static void bshoststart(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 = TAILQ_FIRST(&ti->ti_ctab)) == 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 = TAILQ_FIRST(&ti->ti_ctab);
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 = TAILQ_FIRST(&ti->ti_ctab);
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 = TAILQ_FIRST(&bsc->sc_sttab)) == NULL)
419 return;
420 bs_hostque_delete(bsc, ti);
421 }
422
423 if ((cb = TAILQ_FIRST(&ti->ti_ctab)) == 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 TAILQ_FOREACH(tmpti, &bsc->sc_titab, ti_tchain)
454 if (tmpti->ti_phase >= DISCONNECTED)
455 goto retry;
456 }
457
458 /* start selection */
459 ti->ti_status = ST_UNK;
460 if (bs_check_sat(ti))
461 {
462 if ((bshw_get_auxstat(bsc) & STR_BUSY) == 0)
463 {
464 BS_LOAD_SDP
465 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
466 bshw_setup_ctrl_reg(bsc, ti->ti_cfgflags);
467 bshw_cmd_pass(bsc, 0);
468 bshw_set_sync_reg(bsc, ti->ti_sync);
469 bshw_issue_satcmd(bsc, cb, bs_check_link(ti, cb));
470 if (bs_check_smit(ti) || bsc->sc_p.datalen <= 0)
471 bshw_set_count(bsc, 0);
472 else
473 bs_dma_xfer(ti, BSHW_CMD_CHECK(cb, BSREAD));
474
475 s = splhigh();
476 if ((bshw_get_auxstat(bsc) & STR_BUSY) == 0)
477 {
478 /* XXX:
479 * Reload a lun again here.
480 */
481 bshw_set_lun(bsc, ti->ti_lun);
482 bshw_start_sat(bsc, bs_check_disc(ti));
483 if ((bshw_get_auxstat(bsc) & STR_LCI) == 0)
484 {
485 splx(s);
486 BS_HOST_START
487 BS_SELECTION_START
488 BS_SETUP_PHASE(SATSEL);
489 ti->ti_omsgoutlen = 0;
490 ti->ti_msgout = bs_identify_msg(ti);
491 #ifdef BS_DIAG
492 ti->ti_flags |= BSNEXUS;
493 #endif /* BS_DIAG */
494 #ifdef BS_STATICS
495 bs_statics[ti->ti_id].select_win++;
496 #endif /* BS_STATICS */
497 return;
498 }
499 }
500 splx(s);
501
502 if (bs_check_smit(ti) == 0)
503 bshw_dmaabort(bsc, ti);
504 #ifdef BS_STATICS
505 bs_statics[ti->ti_id].select_miss_in_assert++;
506 #endif /* BS_STATICS */
507 }
508 }
509 else
510 {
511 s = splhigh();
512 if ((bshw_get_auxstat(bsc) & STR_BUSY) == 0)
513 {
514 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
515 bshw_setup_ctrl_reg(bsc, ti->ti_cfgflags);
516 bshw_set_sync_reg(bsc, ti->ti_sync);
517 bshw_assert_select(bsc);
518
519 if ((bshw_get_auxstat(bsc) & STR_LCI) == 0)
520 {
521 splx(s);
522 BS_HOST_START
523 BS_SELECTION_START
524 BS_SETUP_PHASE(SELECTASSERT);
525 #ifdef BS_STATICS
526 bs_statics[ti->ti_id].select_win++;
527 #endif /* BS_STATICS */
528 return;
529 }
530 #ifdef BS_STATICS
531 bs_statics[ti->ti_id].select_miss_in_assert++;
532 #endif /* BS_STATICS */
533 }
534 splx(s);
535 }
536
537 /* RETRY LATER */
538 retry:
539 #ifdef BS_STATICS
540 bs_statics[ti->ti_id].select_miss++;
541 #endif /* BS_STATICS */
542 bs_hostque_head(bsc, ti);
543 BS_SETUP_PHASE(HOSTQUEUE)
544 }
545
546 static BS_INLINE struct targ_info *
547 bs_selected(bsc, ti, cb)
548 struct bs_softc *bsc;
549 struct targ_info *ti;
550 struct bsccb *cb;
551 {
552
553 if (bsc->sc_busstat != BSR_SELECTED)
554 {
555 bs_phase_error(ti, cb);
556 return NULL;
557 }
558
559 #ifdef BS_DIAG
560 if (bsc->sc_selwait != ti)
561 panic("%s selection internal error\n", bsc->sc_dvname);
562
563 ti->ti_flags |= BSNEXUS;
564 #endif /* BS_DIAG */
565
566 /* clear select wait state */
567 BS_SETUP_PHASE(SELECTED);
568 BS_SELECTION_TERMINATE;
569 BS_LOAD_SDP
570 return ti;
571 }
572
573 /**************************************************
574 * <RESELECTION>
575 **************************************************/
576 static BS_INLINE struct targ_info *
577 bs_reselect(bsc)
578 struct bs_softc *bsc;
579 {
580 u_int target;
581 struct targ_info *ti;
582
583 /* check collision */
584 if ((ti = bsc->sc_selwait) != NULL)
585 {
586 if (ti->ti_phase == SATSEL)
587 {
588 #ifdef BS_DIAG
589 ti->ti_flags &= ~BSNEXUS;
590 #endif /* BS_DIAG */
591 ti->ti_msgout = 0;
592 if (bs_check_smit(ti) == 0)
593 bshw_dmaabort(bsc, ti);
594 }
595 bs_hostque_head(bsc, ti);
596 BS_SELECTION_TERMINATE
597 BS_SETUP_PHASE(HOSTQUEUE)
598 #ifdef BS_STATICS
599 bs_statics[ti->ti_id].select_miss_by_reselect++;
600 bs_statics[ti->ti_id].select_miss++;
601 #endif /* BS_STATICS */
602 }
603
604 /* who are you ? */
605 target = bshw_get_src_id(bsc);
606 if ((ti = bsc->sc_ti[target]) == NULL)
607 {
608 bs_debug_print_all(bsc);
609 printf("reselect: miss reselect. target(%d)\n", target);
610 bs_reset_nexus(bsc);
611 return NULL;
612 }
613
614 /* confirm nexus */
615 BS_HOST_START
616 bshw_setup_ctrl_reg(bsc, ti->ti_cfgflags);
617 if (TAILQ_FIRST(&ti->ti_ctab) == NULL || ti->ti_phase != DISCONNECTED)
618 {
619 bs_printf(ti, "reselect", "phase mismatch");
620 BS_SETUP_PHASE(UNDEF)
621 bs_force_abort(ti);
622 bs_hostque_delete(bsc, ti);
623 }
624 else
625 bsc->sc_dtgnum --;
626
627 /* recover host */
628 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
629 bshw_set_sync_reg(bsc, ti->ti_sync);
630 BS_RESTORE_SDP
631 BS_SETUP_PHASE(RESELECTED)
632 #ifdef BS_STATICS
633 bs_statics[ti->ti_id].reselect++;
634 #endif /* BS_STATICS */
635 return ti;
636 }
637
638 static BS_INLINE void
639 bs_sat_continue(bsc, ti, cb)
640 struct bs_softc *bsc;
641 struct targ_info *ti;
642 struct bsccb *cb;
643 {
644
645 BS_SETUP_PHASE(SATRESEL);
646 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
647 bshw_cmd_pass(bsc, 0x44);
648 bshw_set_sync_reg(bsc, ti->ti_sync);
649 bshw_issue_satcmd(bsc, cb, 0);
650 if (bs_check_smit(ti) || bsc->sc_p.datalen <= 0)
651 bshw_set_count(bsc, 0);
652 else
653 bs_dma_xfer(ti, BSHW_CMD_CHECK(cb, BSREAD));
654 bshw_set_lun(bsc, ti->ti_lun); /* XXX */
655 bshw_start_sat(bsc, 0);
656 }
657
658 /*************************************************
659 * <DATA PHASE>
660 *************************************************/
661 #define DR (STR_BSY | STR_DBR)
662
663 void
664 bs_poll_timeout(bsc, s)
665 struct bs_softc *bsc;
666 char *s;
667 {
668 struct targ_info *ti;
669
670 bs_printf(NULL, s, "timeout");
671 bsc->sc_flags |= BSRESET;
672 if ((ti = bsc->sc_nexus) && TAILQ_FIRST(&ti->ti_ctab))
673 ti->ti_error |= BSTIMEOUT;
674 }
675
676 static BS_INLINE u_int8_t
677 bs_read_1byte(bsc)
678 struct bs_softc *bsc;
679 {
680 register u_int wc;
681
682 bshw_start_sxfer(bsc);
683 for (wc = bsc->sc_wc; (bshw_get_auxstat(bsc) & DR) != DR && --wc; );
684 if (wc)
685 return bshw_read_data(bsc);
686 else
687 bs_poll_timeout(bsc, "read_1byte");
688
689 return 0;
690 }
691
692 static BS_INLINE void
693 bs_write_1byte(bsc, data)
694 struct bs_softc *bsc;
695 u_int8_t data;
696 {
697 register u_int wc;
698
699 bshw_start_sxfer(bsc);
700 for (wc = bsc->sc_wc; (bshw_get_auxstat(bsc) & DR) != DR && --wc; );
701 if (wc)
702 bshw_write_data(bsc, data);
703 else
704 bs_poll_timeout(bsc, "write_1byte");
705 }
706
707 static int
708 bs_xfer(bsc, data, len)
709 struct bs_softc *bsc;
710 char *data;
711 int len;
712 {
713 u_int8_t aux;
714 u_int count, wc;
715
716 bshw_set_count(bsc, len);
717 bshw_start_xfer(bsc);
718
719 for (count = 0, wc = bsc->sc_wc; count < len && --wc; )
720 {
721 if (((aux = bshw_get_auxstat(bsc)) & DR) == DR)
722 {
723 if (bsc->sc_busstat & BSHW_READ)
724 *(data++) = bshw_read_data(bsc);
725 else
726 bshw_write_data(bsc, *(data++));
727 count++;
728 wc = bsc->sc_wc;
729 }
730
731 if (aux & STR_INT)
732 break;
733 }
734
735 if (wc == 0)
736 bs_poll_timeout(bsc, "bs_xfer");
737
738 return count;
739 }
740 #undef DR
741
742 static void
743 bs_io_xfer(ti)
744 struct targ_info *ti;
745 {
746 struct bs_softc *bsc = ti->ti_bsc;
747 struct sc_p *sp = &bsc->sc_p;
748 u_int count, dummy;
749
750 /* switch dma trasnfr mode */
751 bshw_set_poll_trans(bsc, ti->ti_cfgflags);
752 sp->seglen = 0;
753 sp->bufp = NULL;
754
755 if (sp->datalen <= 0)
756 {
757 ti->ti_error |= BSDMAABNORMAL;
758 dummy = 0;
759 count = bs_xfer(bsc, (u_int8_t *) &dummy, 1);
760 }
761 else
762 count = bs_xfer(bsc, sp->data, sp->datalen);
763
764 sp->data += count;
765 sp->datalen -= count;
766 }
767
768 /************************************************
769 * <COMMAND PHASE>
770 ************************************************/
771 static BS_INLINE void
772 bs_commandout(bsc, ti, cb)
773 struct bs_softc *bsc;
774 struct targ_info *ti;
775 struct bsccb *cb;
776 {
777 u_int8_t scsi_cmd[16];
778 int len;
779
780 BS_SETUP_PHASE(CMDPHASE);
781
782 if (bs_check_link(ti, cb))
783 {
784 bcopy(cb->cmd, scsi_cmd, cb->cmdlen);
785 scsi_cmd[cb->cmdlen - 1] |= 0x01;
786 len = bs_xfer(bsc, scsi_cmd, cb->cmdlen);
787 }
788 else
789 len = bs_xfer(bsc, cb->cmd, cb->cmdlen);
790
791 if (len != cb->cmdlen)
792 ti->ti_error |= BSCMDABNORMAL;
793 }
794
795 /************************************************
796 * <STATUS IN>
797 ************************************************/
798 static BS_INLINE void
799 bs_status_check(bsc, ti)
800 struct bs_softc *bsc;
801 struct targ_info *ti;
802 {
803
804 if (ti->ti_status == ST_GOOD || ti->ti_status == ST_INTERGOOD)
805 return;
806
807 switch (ti->ti_status)
808 {
809 case ST_MET:
810 case ST_INTERMET:
811 case ST_CHKCOND:
812 ti->ti_error |= BSREQSENSE;
813 break;
814
815 case ST_BUSY:
816 ti->ti_error |= BSTARGETBUSY;
817 break;
818
819 default:
820 ti->ti_error |= BSSTATUSERROR;
821 break;
822 }
823 }
824
825 /************************************************
826 * <MSG IN>
827 ************************************************/
828 #define MSGWAIT(cnt) { if (ti->ti_msginptr < (cnt)) return; }
829
830 static void
831 bs_quick_abort(ti, msg)
832 struct targ_info *ti;
833 u_int msg;
834 {
835 struct bsccb *cb;
836
837 if ((cb = TAILQ_FIRST(&ti->ti_ctab)) == NULL)
838 return;
839
840 cb->msgoutlen = 1;
841 cb->msgout[0] = msg;
842 cb->rcnt++;
843
844 ti->ti_error |= BSMSGERROR;
845 }
846
847 static void
848 bs_msgin_error(ti, count)
849 struct targ_info *ti;
850 u_int count;
851 {
852 int n;
853
854 MSGWAIT(count);
855
856 bs_printf(ti, "msgin", "illegal msg");
857
858 for (n = 0; n < ti->ti_msginptr; n ++)
859 printf("[0x%x] ", (u_int) ti->ti_msgin[n]);
860 printf("\n");
861
862 bs_quick_abort(ti, MSG_REJECT);
863 ti->ti_msginptr = 0;
864 }
865
866 static void
867 bs_msgin_ext(ti)
868 struct targ_info *ti;
869 {
870 struct bs_softc *bsc = ti->ti_bsc;
871 struct bsccb *cb = TAILQ_FIRST(&ti->ti_ctab);
872 int count;
873 u_int reqlen;
874 u_int32_t *ptr;
875 struct msgbase msg;
876
877 MSGWAIT(2);
878
879 reqlen = ti->ti_msgin[1];
880 if (reqlen == 0)
881 reqlen = 256;
882
883 if (ti->ti_msginptr >= MAXMSGLEN)
884 ti->ti_msginptr = 3; /* XXX */
885
886 MSGWAIT(reqlen + 2);
887
888 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
889 {
890 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
891 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
892 count = (int) htonl((long) (*ptr));
893
894 bsc->sc_p.seglen = ti->ti_scsp.seglen = 0;
895 if (bsc->sc_p.datalen - count >= 0 &&
896 bsc->sc_p.datalen - count <= cb->datalen)
897 {
898 bsc->sc_p.datalen -= count;
899 bsc->sc_p.data += count;
900 }
901 else
902 bs_msgin_error(ti, 7);
903 break;
904
905 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
906 ti->ti_syncnow.period = ti->ti_msgin[3];
907 ti->ti_syncnow.offset = ti->ti_msgin[4];
908 if (ti->ti_syncnow.offset == 0)
909 ti->ti_syncnow.period = 0;
910
911 if (ti->ti_syncnow.state != BS_SYNCMSG_ASSERT)
912 {
913 bs_start_syncmsg(ti, NULL, BS_SYNCMSG_REQUESTED);
914 bscmdstart(ti, BSCMDSTART);
915 }
916 else
917 BS_SETUP_SYNCSTATE(BS_SYNCMSG_ACCEPT)
918 break;
919
920 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
921 msg.msglen = MSG_EXTEND_WIDELEN + 2;
922 msg.msg[0] = MSG_EXTEND;
923 msg.msg[1] = MSG_EXTEND_WIDELEN;
924 msg.msg[2] = MSG_EXTEND_WIDECODE;
925 msg.msg[3] = 0;
926 msg.flag = 0;
927 bs_make_msg_ccb(ti, cb->lun, cb, &msg, 0);
928 break;
929
930 default:
931 bs_msgin_error(ti, 0);
932 return;
933 }
934
935 ti->ti_msginptr = 0;
936 return;
937 }
938
939 static void
940 bs_msg_reject(ti)
941 struct targ_info *ti;
942 {
943 struct bs_softc *bsc = ti->ti_bsc;
944 struct bsccb *cb = TAILQ_FIRST(&ti->ti_ctab);
945 char *s = "unexpected msg reject";
946
947 switch (ti->ti_ophase)
948 {
949 case CMDPHASE:
950 s = "cmd rejected";
951 cb->bsccb_flags &= ~BSLINK;
952 BS_SETUP_MSGPHASE(IOCOMPLETED);
953 break;
954
955 case MSGOUT:
956 if (ti->ti_msgout & 0x80)
957 {
958 s = "identify msg rejected";
959 cb->bsccb_flags &= ~BSDISC;
960 BS_SETUP_MSGPHASE(IOCOMPLETED);
961 }
962 else if (ti->ti_msgout == MSG_EXTEND)
963 {
964 switch (ti->ti_emsgout)
965 {
966 case MSG_EXTEND_SYNCHCODE:
967 BS_SETUP_SYNCSTATE(BS_SYNCMSG_REJECT);
968 return;
969
970 default:
971 break;
972 }
973 }
974 break;
975
976 default:
977 break;
978 }
979
980 bs_debug_print(bsc, ti);
981 bs_printf(ti, "msgin", s);
982 ti->ti_error |= BSMSGERROR;
983 }
984
985 static BS_INLINE void
986 bs_msgin(bsc, ti)
987 struct bs_softc *bsc;
988 struct targ_info *ti;
989 {
990
991 BS_SETUP_PHASE(MSGIN);
992
993 switch (ti->ti_msgin[0])
994 {
995 case MSG_SAVESP:
996 BS_SAVE_SDP
997 break;
998
999 case MSG_RESTORESP:
1000 BS_RESTORE_SDP
1001 bs_printf(ti, "msgin", "restore scsi pointer");
1002 break;
1003
1004 case MSG_REJECT:
1005 bs_msg_reject(ti);
1006 break;
1007
1008 case 0xf:
1009 break;
1010
1011 case MSG_I_ERROR:/* all I -> T : nothing to do*/
1012 case MSG_ABORT:
1013 case MSG_PARITY:
1014 case MSG_RESET:
1015 case 0xe:
1016 bs_msgin_error(ti, 1);
1017 goto resume;
1018
1019 case MSG_NOOP:
1020 break;
1021
1022 case MSG_EXTEND:
1023 bs_msgin_ext(ti);
1024 goto resume;
1025
1026 case 0xd:
1027 bs_msgin_error(ti, 2);
1028 goto resume;
1029
1030 case MSG_DISCON:
1031 BS_SETUP_MSGPHASE(DISCONNECTASSERT);
1032 break;
1033
1034 case MSG_COMP:
1035 BS_SETUP_MSGPHASE(IOCOMPLETED);
1036 break;
1037
1038 case MSG_LCOMP:
1039 case MSG_LCOMP_F:
1040 bs_status_check(bsc, ti);
1041 if (bscmddone(ti) == NULL)
1042 {
1043 if (bscmdstart(ti, BSCMDSTART) == 0)
1044 {
1045 bs_printf(ti, "msgin", "cmd line miss");
1046 bs_force_abort(ti);
1047 }
1048 }
1049 else
1050 bscmdstart(ti, BSCMDRESTART);
1051 #ifdef BS_STATICS
1052 bs_linkcmd_count[ti->ti_id]++;
1053 #endif /* BS_STATICS */
1054 BS_LOAD_SDP
1055 ti->ti_status = ST_UNK;
1056 break;
1057
1058 default:
1059 if (ti->ti_msgin[0] & 0x80)
1060 {
1061 if ((ti->ti_msgin[0] & 0x07) != ti->ti_lun)
1062 {
1063 ti->ti_lun = (ti->ti_msgin[0] & 0x07);
1064 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
1065 bshw_set_sync_reg(bsc, ti->ti_sync);
1066
1067 bs_printf(ti, "msgin", "lun error");
1068 bs_quick_abort(ti, MSG_ABORT);
1069 }
1070 break;
1071 }
1072 else if (ti->ti_msgin[0] < 0x20)
1073 bs_msgin_error(ti, 1);
1074 else if (ti->ti_msgin[0] < 0x30)
1075 bs_msgin_error(ti, 2);
1076 else
1077 bs_msgin_error(ti, 1);
1078 goto resume;
1079 }
1080
1081 ti->ti_msginptr = 0;
1082
1083 resume:
1084 return;
1085 }
1086
1087 /************************************************
1088 * <MSG OUT>
1089 ************************************************/
1090 static BS_INLINE void
1091 bs_msgout(bsc, ti, cb)
1092 struct bs_softc *bsc;
1093 struct targ_info *ti;
1094 struct bsccb *cb;
1095 {
1096 u_int8_t msg[MAXMSGLEN + 1];
1097
1098 if (ti->ti_phase == MSGOUT)
1099 {
1100 if (cb->rcnt ++ < bsc->sc_retry)
1101 cb->msgoutlen = ti->ti_omsgoutlen;
1102 }
1103 else
1104 BS_SETUP_PHASE(MSGOUT);
1105
1106 if (ti->ti_ophase == SELECTED)
1107 {
1108 identify:
1109 if (cb->msgoutlen == 0)
1110 {
1111 ti->ti_msgout = bs_identify_msg(ti);
1112 ti->ti_omsgoutlen = 0;
1113 bs_write_1byte(bsc, ti->ti_msgout);
1114 }
1115 else
1116 {
1117 if (cb->msgout[0] != MSG_RESET &&
1118 cb->msgout[0] != MSG_ABORT)
1119 {
1120 msg[0] = bs_identify_msg(ti);
1121 bcopy(cb->msgout, &msg[1], cb->msgoutlen);
1122 bs_xfer(bsc, msg, cb->msgoutlen + 1);
1123 }
1124 else
1125 bs_xfer(bsc, cb->msgout, cb->msgoutlen);
1126
1127 ti->ti_msgout = cb->msgout[0];
1128 ti->ti_emsgout = cb->msgout[2];
1129 ti->ti_omsgoutlen = cb->msgoutlen;
1130 cb->msgoutlen = 0;
1131 }
1132 return;
1133 }
1134
1135 if (ti->ti_ophase == SATSEL)
1136 {
1137 /* XXX:
1138 * Maybe identify msg rejected due to
1139 * a parity error in target side.
1140 */
1141
1142 bs_printf(ti, "msgout", "msg identify retry (SAT)");
1143 goto identify;
1144 }
1145
1146 if (cb->msgoutlen == 0)
1147 {
1148 ti->ti_msgout = MSG_REJECT;
1149 ti->ti_omsgoutlen = 0;
1150 bs_write_1byte(bsc, ti->ti_msgout);
1151 }
1152 else
1153 {
1154 ti->ti_msgout = cb->msgout[0];
1155 ti->ti_emsgout = cb->msgout[2];
1156 ti->ti_omsgoutlen = cb->msgoutlen;
1157 bs_xfer(bsc, cb->msgout, cb->msgoutlen);
1158 cb->msgoutlen = 0;
1159 }
1160 }
1161
1162 /************************************************
1163 * <DISCONNECT>
1164 ************************************************/
1165 static BS_INLINE void
1166 bs_disconnect_phase(bsc, ti, cb)
1167 struct bs_softc *bsc;
1168 struct targ_info *ti;
1169 struct bsccb *cb;
1170 {
1171
1172 switch (bsc->sc_msgphase)
1173 {
1174 default:
1175 panic("%s unknown msg phase\n", bsc->sc_dvname);
1176 break;
1177
1178 case DISCONNECTASSERT:
1179 case FREE:
1180 #ifdef BS_STATICS
1181 bs_statics[ti->ti_id].disconnected++;
1182 #endif /* BS_STATICS */
1183 if (ti->ti_cfgflags & BS_SCSI_SAVESP)
1184 BS_SAVE_SDP;
1185 BS_HOST_TERMINATE;
1186 BS_SETUP_PHASE(DISCONNECTED);
1187 bsc->sc_dtgnum ++;
1188 bshoststart(bsc, NULL);
1189 break;
1190
1191 case IOCOMPLETED:
1192 bs_status_check(bsc, ti);
1193 cb = bscmddone(ti);
1194 #ifdef BS_DIAG
1195 ti->ti_flags &= ~BSNEXUS;
1196 #endif /* BS_DIAG */
1197 BS_SETUP_PHASE(FREE);
1198 if (cb || TAILQ_FIRST(&bsc->sc_sttab) == NULL)
1199 {
1200 BS_HOST_TERMINATE;
1201 bscmdstart(ti, BSCMDSTART);
1202 }
1203 else
1204 {
1205 /* give a chance to other target */
1206 bscmdstart(ti, BSCMDSTART);
1207 BS_HOST_TERMINATE;
1208 bshoststart(bsc, NULL);
1209 }
1210 break;
1211 }
1212
1213 BS_SETUP_MSGPHASE(FREE);
1214 }
1215
1216 /**************************************************
1217 * <PHASE ERROR>
1218 **************************************************/
1219 #define scsi_status (bsc->sc_busstat)
1220
1221 struct bs_err {
1222 u_char *pe_msg;
1223 u_int pe_err;
1224 u_int pe_ph;
1225 };
1226
1227 struct bs_err bs_cmderr[] = {
1228 /**/ { "illegal cmd", BSABNORMAL, UNDEF },
1229 /*1*/ { "unexpected bus free", BSABNORMAL, FREE },
1230 /*2*/ { NULL, BSSELTIMEOUT, FREE},
1231 /*3*/ { "scsi bus parity error", BSPARITY, UNDEF },
1232 /*4*/ { "scsi bus parity error", BSPARITY, UNDEF },
1233 /*5*/ { "unknown" , BSFATALIO, UNDEF },
1234 /*6*/ { "miss reselection (target mode)", BSFATALIO, UNDEF },
1235 /*7*/ { "wrong status byte", BSPARITY, STATUSIN },
1236 };
1237
1238 static void
1239 bs_phase_error(ti, cb)
1240 struct targ_info *ti;
1241 struct bsccb *cb;
1242 {
1243 struct bs_softc *bsc = ti->ti_bsc;
1244 struct bs_err *pep;
1245
1246 if ((scsi_status & BSR_CM) == BSR_CMDERR &&
1247 (scsi_status & BSR_PHVALID) == 0)
1248 {
1249 pep = &bs_cmderr[scsi_status & BSR_PM];
1250 ti->ti_error |= pep->pe_err;
1251 if (pep->pe_msg)
1252 {
1253 bs_debug_print(bsc, ti);
1254 bs_printf(ti, "bsintr", pep->pe_msg);
1255 }
1256 BS_SETUP_PHASE(pep->pe_ph);
1257 }
1258 else
1259 {
1260 ti->ti_error |= BSABNORMAL;
1261 bs_debug_print(bsc, ti);
1262 bs_printf(ti, "bsintr", "phase error");
1263 BS_SETUP_PHASE(UNDEF);
1264 }
1265
1266 BS_SETUP_MSGPHASE(FREE);
1267 switch (ti->ti_phase)
1268 {
1269 case FREE:
1270 BS_SETUP_PHASE(UNDEF);
1271 cb = bscmddone(ti);
1272 #ifdef BS_DIAG
1273 ti->ti_flags &= ~BSNEXUS;
1274 #endif /* BS_DIAG */
1275 BS_HOST_TERMINATE;
1276 BS_SETUP_PHASE(FREE);
1277 bscmdstart(ti, ((cb == NULL) ? BSCMDSTART : BSCMDRESTART));
1278 break;
1279
1280 case STATUSIN:
1281 ti->ti_error |= BSSTATUSERROR;
1282 ti->ti_status = bshw_get_status_insat(bsc); /* XXX SAT */
1283 bs_debug_print(bsc, ti);
1284 break;
1285
1286 case UNDEF:
1287 default:
1288 ti->ti_error |= BSABNORMAL;
1289 bs_reset_nexus(bsc);
1290 break;
1291 }
1292 }
1293
1294 /**************************************************
1295 * ### SCSI PHASE SEQUENCER ###
1296 **************************************************/
1297 static BS_INLINE void bs_ack_wait(struct bs_softc *, struct targ_info *, struct bsccb *);
1298
1299 static BS_INLINE void
1300 bs_ack_wait(bsc, ti, cb)
1301 struct bs_softc *bsc;
1302 struct targ_info *ti;
1303 struct bsccb *cb;
1304 {
1305 int wc = bsc->sc_wc;
1306
1307 for (wc = bsc->sc_wc; bshw_get_busstat(bsc) != BSR_ACKREQ && wc > 0; )
1308 wc --;
1309
1310 if (wc <= 0)
1311 {
1312 bs_printf(ti, "bs_ack_wait", "timeout I");
1313 return;
1314 }
1315
1316 bshw_get_auxstat(bsc);
1317 scsi_status = bshw_get_busstat(bsc);
1318
1319 if (cb->msgoutlen > 0)
1320 {
1321 bshw_assert_atn(bsc);
1322 delay(800);
1323 BS_SETUP_PHASE(ATTENTIONASSERT);
1324 }
1325
1326 bshw_negate_ack(bsc);
1327
1328 #ifdef WAITNEXTP
1329 for (wc = bsc->sc_wc; bshw_get_busstat(bsc) == BSR_ACKREQ && wc > 0; )
1330 wc --;
1331
1332 if (wc <= 0)
1333 bs_printf(ti, "bs_ack_wait", "timeout II");
1334 #endif /* WAITNEXTP */
1335 }
1336
1337 int
1338 bs_sequencer(bsc)
1339 struct bs_softc *bsc;
1340 {
1341 register struct targ_info *ti;
1342 struct bsccb *cb;
1343
1344 /**************************************************
1345 * Check reset
1346 **************************************************/
1347 if (bsc->sc_flags & (BSRESET | BSINACTIVE))
1348 {
1349 if (bsc->sc_flags & BSRESET)
1350 bs_reset_nexus(bsc);
1351 return 1;
1352 }
1353
1354 /**************************************************
1355 * Get status & bus phase
1356 **************************************************/
1357 if ((bshw_get_auxstat(bsc) & STR_INT) == 0)
1358 return 0;
1359
1360 scsi_status = bshw_get_busstat(bsc);
1361 if (scsi_status == ((u_int8_t) -1))
1362 {
1363 bs_debug_print_all(bsc);
1364 return 1;
1365 }
1366 /**************************************************
1367 * Check reselection, or nexus
1368 **************************************************/
1369 if (scsi_status == BSR_RESEL)
1370 {
1371 bs_reselect(bsc);
1372 return 1;
1373 }
1374
1375 ti = bsc->sc_nexus;
1376 if (ti == NULL || (cb = TAILQ_FIRST(&ti->ti_ctab)) == NULL)
1377 {
1378 bs_debug_print_all(bsc);
1379 bs_printf(ti, "bsintr", "no nexus");
1380 bs_reset_nexus(bsc);
1381 return 1;
1382 }
1383
1384 /**************************************************
1385 * Debug section
1386 **************************************************/
1387 #ifdef BS_DEBUG
1388 if (bs_debug_flag)
1389 {
1390 bs_debug_print(bsc, ti);
1391 if (bs_debug_flag > 1)
1392 Debugger();
1393 }
1394 #endif /* BS_DEBUG */
1395
1396 /**************************************************
1397 * internal scsi phase
1398 **************************************************/
1399 switch (ti->ti_phase)
1400 {
1401 case SELECTASSERT:
1402 bs_selected(bsc, ti, cb);
1403 return 1;
1404
1405 case SATSEL:
1406 BS_SELECTION_TERMINATE;
1407
1408 case SATRESEL:
1409 if (bsc->sc_flags & (BSDMASTART | BSSMITSTART))
1410 {
1411 if (bsc->sc_flags & BSSMITSTART)
1412 {
1413 bs_debug_print_all(bsc);
1414 bs_reset_nexus(bsc);
1415 bs_printf(ti, "bsintr", "smit transfer");
1416 return 1;
1417 }
1418
1419 BS_SETUP_PHASE(DATAPHASE); /* XXX */
1420 bs_dma_xfer_end(ti);
1421 ti->ti_phase = ti->ti_ophase; /* XXX */
1422 }
1423 break;
1424
1425 default:
1426 /* XXX:
1427 * check check check for safety !!
1428 */
1429 if (bsc->sc_selwait)
1430 {
1431 /* Ghaaa! phase error! retry! */
1432 bs_phase_error(ti, cb);
1433 return 1;
1434 }
1435
1436 if (bsc->sc_flags & (BSDMASTART | BSSMITSTART))
1437 {
1438 if (bsc->sc_flags & BSDMASTART)
1439 bs_dma_xfer_end(ti);
1440 else
1441 bs_smit_xfer_end(ti);
1442 }
1443 break;
1444 }
1445
1446 /**************************************************
1447 * hw scsi phase
1448 **************************************************/
1449 if (scsi_status & BSR_PHVALID)
1450 {
1451 /**************************************************
1452 * Normal SCSI phase.
1453 **************************************************/
1454 if ((scsi_status & BSR_CM) == BSR_CMDABT)
1455 {
1456 bs_phase_error(ti, cb);
1457 return 1;
1458 }
1459
1460 switch (scsi_status & BSR_PM)
1461 {
1462 case BSR_DATAOUT:
1463 case BSR_DATAIN:
1464 BS_SETUP_PHASE(DATAPHASE);
1465
1466 if (bsc->sc_p.datalen <= 0 ||
1467 (ti->ti_flags & BSFORCEIOPOLL))
1468 {
1469 bs_io_xfer(ti);
1470 return 1;
1471 }
1472
1473 if (bs_check_smit(ti) &&
1474 (bsc->sc_p.datalen % sizeof(u_int32_t)) == 0)
1475 {
1476 bs_lc_smit_xfer(ti, scsi_status & BSR_IOR);
1477 return 1;
1478 }
1479
1480 bs_dma_xfer(ti, scsi_status & BSR_IOR);
1481 bshw_start_xfer(bsc);
1482 return 1;
1483
1484 case BSR_CMDOUT:
1485 bs_commandout(bsc, ti, cb);
1486 return 1;
1487
1488 case BSR_STATIN:
1489 if (bs_check_sat(ti))
1490 {
1491 BS_SETUP_PHASE(SATCOMPSEQ);
1492 bshw_set_count(bsc, 0);
1493 bshw_cmd_pass(bsc, 0x41);
1494 bshw_start_sat(bsc, 0);
1495 }
1496 else
1497 {
1498 BS_SETUP_PHASE(STATUSIN);
1499 ti->ti_status = bs_read_1byte(bsc);
1500 }
1501 return 1;
1502
1503 case BSR_UNSPINFO0:
1504 case BSR_UNSPINFO1:
1505 bs_debug_print(bsc, ti);
1506 bs_printf(ti, "bsintr", "illegal bus phase");
1507 return 1;
1508
1509 case BSR_MSGOUT:
1510 bs_msgout(bsc, ti, cb);
1511 return 1;
1512
1513 case BSR_MSGIN:/* msg in */
1514 if (bs_check_sat(ti))
1515 {
1516 if (ti->ti_phase == RESELECTED)
1517 {
1518 bs_sat_continue(bsc, ti, cb);
1519 return 1;
1520 }
1521 /* XXX */
1522 if (ti->ti_status == ST_UNK)
1523 ti->ti_status = bshw_get_status_insat(bsc);
1524 }
1525
1526 ti->ti_msgin[ti->ti_msginptr ++] = bs_read_1byte(bsc);
1527 bs_msgin(bsc, ti);
1528 if (bsc->sc_cfgflags & BSC_FASTACK)
1529 bs_ack_wait(bsc, ti, cb);
1530
1531 return 1;
1532 }
1533 }
1534 else
1535 {
1536 /**************************************************
1537 * Special SCSI phase
1538 **************************************************/
1539 switch (scsi_status)
1540 {
1541 case BSR_SATSDP:/* SAT with save data pointer */
1542 BS_SAVE_SDP
1543 bshw_cmd_pass(bsc, 0x41);
1544 bshw_start_sat(bsc, 0);
1545 BS_SETUP_PHASE(SATSDP)
1546 return 1;
1547
1548 case BSR_SATFIN:/* SAT COMPLETE */
1549 ti->ti_status = bshw_get_status_insat(bsc);
1550 BS_SETUP_MSGPHASE(IOCOMPLETED);
1551 bs_disconnect_phase(bsc, ti, cb);
1552 return 1;
1553
1554 case BSR_ACKREQ:/* negate ACK */
1555 if (cb->msgoutlen > 0)
1556 {
1557 bshw_assert_atn(bsc);
1558 delay(800);
1559 BS_SETUP_PHASE(ATTENTIONASSERT);
1560 }
1561 bshw_negate_ack(bsc);
1562 return 1;
1563
1564 case BSR_DISC:/* disconnect */
1565 bs_disconnect_phase(bsc, ti, cb);
1566 return 1;
1567
1568 default:
1569 break;
1570 }
1571 }
1572
1573 bs_phase_error(ti, cb);
1574 return 1;
1575 }
1576
1577 /*****************************************************************
1578 * INTERNAL POLLING FUNCTIONS
1579 *****************************************************************/
1580 static int
1581 bs_scsi_cmd_poll_internal(cti)
1582 struct targ_info *cti;
1583 {
1584 struct bs_softc *bsc = cti->ti_bsc;
1585 struct targ_info *ti;
1586 struct bsccb *cb;
1587 int i, waits, delay_count;
1588
1589 bsc->sc_poll++;
1590
1591 /* setup timeout count */
1592 if ((ti = bsc->sc_nexus) == NULL ||
1593 (cb = TAILQ_FIRST(&ti->ti_ctab)) == NULL)
1594 waits = BS_DEFAULT_TIMEOUT_SECOND * 1000000;
1595 else
1596 waits = cb->tcmax * 1000000;
1597
1598 /* force all current jobs into the polling state. */
1599 for (i = 0; i < NTARGETS; i++)
1600 {
1601 if ((ti = bsc->sc_ti[i]) != NULL)
1602 {
1603 ti->ti_flags |= BSFORCEIOPOLL;
1604 if ((cb = TAILQ_FIRST(&ti->ti_ctab)) != NULL)
1605 cb->bsccb_flags |= BSFORCEIOPOLL;
1606 }
1607 }
1608
1609 /* do io */
1610 bsc->sc_flags &= ~BSJOBDONE;
1611 do
1612 {
1613 delay_count = ((bsc->sc_flags & BSDMASTART) ? 1000000 : 100);
1614 delay(delay_count);
1615 waits -= delay_count;
1616 bs_sequencer(bsc);
1617 }
1618 while (waits >= 0 && (bsc->sc_flags & (BSUNDERRESET | BSJOBDONE)) == 0);
1619
1620 /* done */
1621 bsc->sc_poll--;
1622 if (waits < 0 || (bsc->sc_flags & BSUNDERRESET))
1623 {
1624 bs_printf(NULL, "cmd_poll", "timeout or fatal");
1625 return HASERROR;
1626 }
1627
1628 return COMPLETE;
1629 }
1630
1631 int
1632 bs_scsi_cmd_poll(cti, targetcb)
1633 struct targ_info *cti;
1634 struct bsccb *targetcb;
1635 {
1636 struct bs_softc *bsc = cti->ti_bsc;
1637 struct targ_info *ti;
1638 int s, error = COMPLETE;
1639
1640 s = splcam();
1641 bs_terminate_timeout(bsc);
1642
1643 if (bsc->sc_hstate == BSC_TARG_CHECK)
1644 {
1645 if ((error = bs_scsi_cmd_poll_internal(cti)) != COMPLETE)
1646 bs_reset_nexus(bsc);
1647 }
1648 else
1649 {
1650 if (bsc->sc_outccb)
1651 bs_panic(bsc, "bs_cmd_poll: internal error");
1652
1653 bsc->sc_flags &= ~BSPOLLDONE;
1654 bsc->sc_outccb = targetcb;
1655
1656 while ((bsc->sc_flags & BSPOLLDONE) == 0)
1657 {
1658 if (bs_scsi_cmd_poll_internal(cti) != COMPLETE)
1659 {
1660 if ((ti = bsc->sc_nexus) && TAILQ_FIRST(&ti->ti_ctab))
1661 ti->ti_error |= (BSTIMEOUT | BSABNORMAL);
1662 bs_reset_nexus(bsc);
1663 }
1664 }
1665
1666 bsc->sc_outccb = NULL;
1667 }
1668
1669 bs_start_timeout(bsc);
1670 softintr(bsc->sc_irq);
1671 splx(s);
1672 return error;
1673 }
Cache object: 99da45df2873e866280d46f4091583e2
|