]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/i386/isa/bs/bsfunc.c
This commit was generated by cvs2svn to compensate for changes in r50760,
[FreeBSD/FreeBSD.git] / sys / i386 / isa / bs / bsfunc.c
1 /*      $NecBSD: bsfunc.c,v 1.2 1997/10/31 17:43:37 honda Exp $ */
2 /*      $NetBSD$        */
3 /*
4  * [NetBSD for NEC PC98 series]
5  *  Copyright (c) 1994, 1995, 1996 NetBSD/pc98 porting staff.
6  *  All rights reserved.
7  * 
8  *  Redistribution and use in source and binary forms, with or without
9  *  modification, are permitted provided that the following conditions
10  *  are met:
11  *  1. Redistributions of source code must retain the above copyright
12  *     notice, this list of conditions and the following disclaimer.
13  *  2. Redistributions in binary form must reproduce the above copyright
14  *     notice, this list of conditions and the following disclaimer in the
15  *     documentation and/or other materials provided with the distribution.
16  *  3. The name of the author may not be used to endorse or promote products
17  *     derived from this software without specific prior written permission.
18  * 
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 /*
32  * Copyright (c) 1994, 1995, 1996 Naofumi HONDA.  All rights reserved.
33  */
34
35 #ifdef  __NetBSD__
36 #include <i386/Cbus/dev/bs/bsif.h>
37 #endif
38 #ifdef  __FreeBSD__
39 #include <i386/isa/bs/bsif.h>
40 #endif
41
42 #ifdef  BS_STATICS
43 struct bs_statics bs_statics[NTARGETS];
44 u_int bs_linkcmd_count[NTARGETS];
45 u_int bs_bounce_used[NTARGETS];
46 #endif  /* BS_STATICS */
47
48 #ifdef  BS_DEBUG
49 int bs_debug_flag = 0;
50 #endif  /* BS_DEBUG */
51
52 static void bs_print_syncmsg __P((struct targ_info *, char*));
53 static void bs_timeout_target __P((struct targ_info *));
54 static void bs_kill_msg __P((struct bsccb *cb));
55
56 static int bs_start_target __P((struct targ_info *));
57 static int bs_check_target __P((struct targ_info *));
58
59 /*************************************************************
60  * CCB
61  ************************************************************/
62 GENERIC_CCB_STATIC_ALLOC(bs, bsccb)
63 GENERIC_CCB(bs, bsccb, ccb_chain)
64
65 /*************************************************************
66  * TIMEOUT
67  ************************************************************/
68 static void
69 bs_timeout_target(ti)
70         struct targ_info *ti;
71 {
72         struct bs_softc *bsc = ti->ti_bsc;
73
74         ti->ti_error |= BSTIMEOUT;
75         bsc->sc_flags |= BSRESET;
76
77         if (ti->ti_herrcnt ++ >= HARDRETRIES)
78         {
79                 bs_printf(ti, "timeout", "async transfer!");
80                 ti->ti_syncmax.period = ti->ti_syncmax.offset = 0;
81         }
82 }
83
84 void
85 bstimeout(arg)
86         void *arg;
87 {
88         struct bs_softc *bsc = (struct bs_softc *) arg;
89         struct targ_info *ti;
90         struct bsccb *cb;
91         int s;
92
93         s = splbio();
94         bsc->sc_flags &= ~BSSTARTTIMEOUT;
95
96         /* check */
97         if ((ti = bsc->sc_nexus) && (cb = ti->ti_ctab.tqh_first))
98         {
99                 if ((cb->tc -= BS_TIMEOUT_CHECK_INTERVAL) < 0)
100                         bs_timeout_target(ti);
101         }
102         else for (ti = bsc->sc_titab.tqh_first; ti; ti = ti->ti_tchain.tqe_next)
103         {
104                 if (bsc->sc_dtgnum && ti->ti_phase < DISCONNECTED)
105                         continue;
106
107                 cb = ti->ti_ctab.tqh_first;
108                 if (cb && ((cb->tc -= BS_TIMEOUT_CHECK_INTERVAL) < 0))
109                         bs_timeout_target(ti);
110         }
111
112         /* try to recover */
113         if (bsc->sc_flags & BSRESET)
114         {
115                 bs_debug_print_all(bsc);
116                 bs_printf(ti, "timeout", "bus hang up");
117                 bs_reset_nexus(bsc);
118         }
119
120         bs_start_timeout(bsc);
121         splx(s);
122 }
123
124 /**************************************************
125  * MAKE CCB & MSG CCB
126  *************************************************/
127 static u_int8_t cmd_unit_ready[6];
128
129 struct bsccb *
130 bs_make_internal_ccb(ti, lun, cmd, cmdlen, data, datalen, flags, timeout)
131         struct targ_info *ti;
132         u_int lun;
133         u_int8_t *cmd;
134         u_int cmdlen;
135         u_int8_t *data;
136         u_int datalen;
137         u_int flags;
138         int timeout;
139 {
140         struct bsccb *cb;
141
142         if ((cb = bs_get_ccb()) == NULL)
143                 bs_panic(ti->ti_bsc, "can not get ccb mem");
144
145         cb->ccb = NULL;
146         cb->lun = lun;
147         cb->cmd = (cmd ? cmd : cmd_unit_ready);
148         cb->cmdlen = (cmd ? cmdlen : sizeof(cmd_unit_ready));
149         cb->data = data;
150         cb->datalen = (data ? datalen : 0);
151         cb->msgoutlen = 0;
152         cb->bsccb_flags = flags & BSCFLAGSMASK;
153         bs_targ_flags(ti, cb);
154         cb->rcnt = 0;
155         cb->tcmax = (timeout > BS_DEFAULT_TIMEOUT_SECOND ? timeout :
156                                 BS_DEFAULT_TIMEOUT_SECOND);
157
158         TAILQ_INSERT_HEAD(&ti->ti_ctab, cb, ccb_chain);
159
160         return cb;
161 }
162
163 struct bsccb *
164 bs_make_msg_ccb(ti, lun, cb, msg, timex)
165         struct targ_info *ti;
166         u_int lun;
167         struct bsccb *cb;
168         struct msgbase *msg;
169         u_int timex;
170 {
171         u_int flags;
172
173         flags = BSFORCEIOPOLL | msg->flag;
174         if (cb == NULL)
175                 cb = bs_make_internal_ccb(ti, lun, NULL, 0, NULL, 0,
176                                            flags, timex);
177         else
178                 cb->bsccb_flags |= flags & BSCFLAGSMASK;
179
180         cb->msgoutlen = msg->msglen;
181         bcopy(msg->msg, cb->msgout, msg->msglen);
182         return cb;
183 }
184
185 int
186 bs_send_msg(ti, lun, msg, timex)
187         struct targ_info *ti;
188         u_int lun;
189         struct msgbase *msg;
190         int timex;
191 {
192         struct bsccb *cb;
193
194         cb = bs_make_msg_ccb(ti, lun, NULL, msg, timex);
195         bscmdstart(ti, BSCMDSTART);
196         return bs_scsi_cmd_poll(ti, cb);
197 }
198
199 static void
200 bs_kill_msg(cb)
201         struct bsccb *cb;
202 {
203         cb->msgoutlen = 0;
204 }
205
206 /**************************************************
207  * MAKE SENSE CCB
208  **************************************************/
209 struct bsccb *
210 bs_request_sense(ti)
211         struct targ_info *ti;
212 {
213         struct bsccb *cb;
214
215         bzero(ti->scsi_cmd, sizeof(struct scsi_sense));
216         bzero(&ti->sense, sizeof(struct scsi_sense_data));
217         ti->scsi_cmd[0] = REQUEST_SENSE;
218         ti->scsi_cmd[1] = (ti->ti_lun << 5);
219         ti->scsi_cmd[4] = sizeof(struct scsi_sense_data);
220         cb = bs_make_internal_ccb(ti, ti->ti_lun, ti->scsi_cmd,
221                                      sizeof(struct scsi_sense),
222                                      (u_int8_t *) & ti->sense,
223                                      sizeof(struct scsi_sense_data),
224                                      BSFORCEIOPOLL,
225                                      BS_DEFAULT_TIMEOUT_SECOND);
226         cb->bsccb_flags |= BSSENSECCB;
227         return cb;
228 }
229
230 /**************************************************
231  * SYNC MSG
232  *************************************************/
233 /* sync neg */
234 int
235 bs_start_syncmsg(ti, cb, flag)
236         struct targ_info *ti;
237         struct bsccb *cb;
238         int flag;
239 {
240         struct syncdata *negp, *maxp;
241         struct msgbase msg;
242         u_int lun;
243
244         negp = &ti->ti_syncnow;
245         maxp = &ti->ti_syncmax;
246
247         ti->ti_state = BS_TARG_SYNCH;
248
249         if (flag == BS_SYNCMSG_REQUESTED)
250         {
251                 if (negp->offset > maxp->offset)
252                         negp->offset = maxp->offset;
253                 if (negp->offset != 0 && negp->period < maxp->period)
254                         negp->period = maxp->period;
255
256                 msg.flag = 0;
257                 lun = ti->ti_lun;
258                 if (cb == NULL)
259                         cb = ti->ti_ctab.tqh_first;
260         }
261         else if (ti->ti_cfgflags & BS_SCSI_SYNC)
262         {
263                 negp->offset = maxp->offset;
264                 negp->period = maxp->period;
265
266                 msg.flag = BSERROROK;
267                 lun = 0;
268         }
269         else
270         {
271                 ti->ti_state = BS_TARG_RDY;
272                 return COMPLETE;
273         }
274
275         BS_SETUP_SYNCSTATE(flag);
276         msg.msg[0] = MSG_EXTEND;
277         msg.msg[1] = MSG_EXTEND_SYNCHLEN;
278         msg.msg[2] = MSG_EXTEND_SYNCHCODE;
279         msg.msg[3] = negp->period;
280         msg.msg[4] = negp->offset;
281         msg.msglen = MSG_EXTEND_SYNCHLEN + 2;
282
283         bs_make_msg_ccb(ti, lun, cb, &msg, BS_SYNC_TIMEOUT);
284         return COMPLETE;
285 }
286
287 static void
288 bs_print_syncmsg(ti, s)
289         struct targ_info *ti;
290         char *s;
291 {
292         struct bs_softc *bsc = ti->ti_bsc;
293         struct syncdata *negp;
294         u_int speed;
295
296         negp = &ti->ti_syncnow;
297         speed = (negp->offset && negp->period) ?
298                 (2500 / ((u_int) negp->period)) : 0;
299
300         printf("%s(%d:%d): <%s> ", bsc->sc_dvname, ti->ti_id, ti->ti_lun, s);
301         printf("period 0x%x offset %d chip (0x%x)", negp->period, negp->offset,
302                 ti->ti_sync);
303         if (speed)
304                 printf(" %d.%d M/s", speed / 10, speed % 10);
305         printf("\n");
306 }
307
308 int
309 bs_analyze_syncmsg(ti, cb)
310         struct targ_info *ti;
311         struct bsccb *cb;
312 {
313         struct bs_softc *bsc = ti->ti_bsc;
314         u_int8_t ans = ti->ti_syncnow.state;
315         struct syncdata *negp, *maxp;
316         struct syncdata bdata;
317         char *s = NULL;
318         u_int8_t period;
319
320         negp = &ti->ti_syncnow;
321         bdata = *negp;
322         maxp = &ti->ti_syncmax;
323
324         switch(ans)
325         {
326         case BS_SYNCMSG_REJECT:
327                 period = 0;
328                 s = "msg reject";
329                 break;
330
331         case BS_SYNCMSG_ASSERT:
332                 period = 0;
333                 s = "no msg";
334                 break;
335
336         default:
337                 if (negp->offset != 0 && negp->period < maxp->period)
338                 {
339                         period = 0xff;
340                         s = "illegal(period)";
341                 }
342                 else if (negp->offset > maxp->offset)
343                 {
344                         period = 0xff;
345                         s = "illegal(offset)";
346                 }
347                 else
348                         period = negp->offset ? negp->period : 0;
349                 break;
350         }
351
352         if (s == NULL)
353         {
354                 bshw_adj_syncdata(negp);
355                 *maxp = *negp;
356
357                 if (ans == BS_SYNCMSG_REQUESTED)
358                         s = "requested";
359                 else
360                         s = negp->offset ? "synchronous" : "async";
361         }
362         else
363         {
364                 negp->offset = maxp->offset = 0;
365                 bshw_adj_syncdata(negp);
366                 bshw_adj_syncdata(maxp);
367         }
368
369         /* really setup hardware */
370         bshw_set_synchronous(bsc, ti);
371         if (cb == NULL || (period >= negp->period && period <= negp->period + 2))
372         {
373                 bs_print_syncmsg(ti, s);
374                 BS_SETUP_TARGSTATE(BS_TARG_RDY);
375                 BS_SETUP_SYNCSTATE(BS_SYNCMSG_NULL);
376                 if (cb)
377                         bs_kill_msg(cb);
378
379                 return 0;
380         }
381         else
382         {
383                 bs_printf(ti, "bs_analyze_syncmsg",
384                           "sync(period) mismatch, retry neg...");
385                 printf("expect(%d:0x%x) => reply(%d:0x%x)\n",
386                         bdata.offset, bdata.period, negp->offset, negp->period);
387
388                 bs_start_syncmsg(ti, cb, BS_SYNCMSG_ASSERT);
389                 return EINVAL;
390         }
391 }
392
393 /**************************************************
394  * ABORT AND RESET MSG
395  **************************************************/
396 /* send device reset msg and wait */
397 void
398 bs_reset_device(ti)
399         struct targ_info *ti;
400 {
401         struct msgbase msg;
402
403         msg.msglen = 1;
404         msg.msg[0] = MSG_RESET;
405         msg.flag = 0;
406
407         bs_send_msg(ti, 0, &msg, 0);
408
409         delay(ti->ti_bsc->sc_RSTdelay);
410         bs_check_target(ti);
411 }
412
413 /* send abort msg */
414 struct bsccb *
415 bs_force_abort(ti)
416         struct targ_info *ti;
417 {
418         struct bs_softc *bsc = ti->ti_bsc;
419         struct msgbase msg;
420         struct bsccb *cb = ti->ti_ctab.tqh_first;
421         u_int lun;
422
423         if (cb)
424         {
425                 lun = cb->lun;
426                 cb->rcnt++;
427         }
428         else
429                 lun = 0;
430
431         msg.msglen = 1;
432         msg.msg[0] = MSG_ABORT;
433         msg.flag = 0;
434
435         cb = bs_make_msg_ccb(ti, lun, NULL, &msg, 0);
436         bscmdstart(ti, BSCMDSTART);
437
438         if (bsc->sc_nexus == ti)
439                 BS_LOAD_SDP
440
441         return cb;
442 }
443
444 /**************************************************
445  * COMPLETE SCSI BUS RESET
446  *************************************************/
447 /*
448  * XXX:
449  * 1) reset scsi bus (ie. all target reseted).
450  * 2) chip reset.
451  * 3) check target status.
452  * 4) sync neg with all targets.
453  * 5) setup sync reg in host.
454  * 6) recover previous nexus.
455  */
456 void
457 bs_scsibus_start(bsc)
458         struct bs_softc *bsc;
459 {
460         struct targ_info *ti, *nextti = NULL;
461         int error = HASERROR;
462         u_int querm, bits, skip = 0;
463
464         querm = (bsc->sc_hstate == BSC_BOOTUP);
465         bsc->sc_hstate = BSC_TARG_CHECK;
466
467         /* target check */
468         do
469         {
470                 if (error != COMPLETE)
471                 {
472                         printf("%s: scsi bus reset and try to restart ...",
473                                bsc->sc_dvname);
474                         bshw_smitabort(bsc);
475                         bshw_dmaabort(bsc, NULL);
476                         bshw_chip_reset(bsc);
477                         bshw_bus_reset(bsc);
478                         bshw_chip_reset(bsc);
479                         printf(" done. scsi bus ready.\n");
480                         nextti = bsc->sc_titab.tqh_first;
481                         error = COMPLETE;
482                 }
483
484                 if ((ti = nextti) == NULL)
485                         break;
486                 nextti = ti->ti_tchain.tqe_next;
487
488                 bits = (1 << ti->ti_id);
489                 if (skip & bits)
490                         continue;
491
492                 if ((error = bs_check_target(ti)) != COMPLETE)
493                 {
494                         if (querm)
495                         {
496                                 TAILQ_REMOVE(&bsc->sc_titab, ti, ti_tchain);
497                                 bsc->sc_openf &= ~bits;
498                         }
499
500                         if (error == NOTARGET)
501                                 error = COMPLETE;
502
503                         skip |= bits;
504                 }
505         }
506         while (1);
507
508         /* ok now ready */
509         bsc->sc_hstate = BSC_RDY;
510
511         /* recover */
512         for (ti = bsc->sc_titab.tqh_first; ti; ti = ti->ti_tchain.tqe_next)
513         {
514                 ti->ti_ctab = ti->ti_bctab;
515                 TAILQ_INIT(&ti->ti_bctab);
516                 if (ti->ti_ctab.tqh_first)
517                         bscmdstart(ti, BSCMDSTART);
518         }
519 }
520
521 void
522 bs_reset_nexus(bsc)
523         struct bs_softc *bsc;
524 {
525         struct targ_info *ti;
526         struct bsccb *cb;
527
528         bsc->sc_flags &= ~(BSRESET | BSUNDERRESET);
529         if (bsc->sc_poll)
530         {
531                 bsc->sc_flags |= BSUNDERRESET;
532                 return;
533         }
534
535         /* host state clear */
536         BS_HOST_TERMINATE
537         BS_SETUP_MSGPHASE(FREE)
538         bsc->sc_dtgnum = 0;
539
540         /* target state clear */
541         for (ti = bsc->sc_titab.tqh_first; ti; ti = ti->ti_tchain.tqe_next)
542         {
543                 if (ti->ti_state == BS_TARG_SYNCH)
544                         bs_analyze_syncmsg(ti, NULL);
545                 if (ti->ti_state > BS_TARG_START)
546                         BS_SETUP_TARGSTATE(BS_TARG_START);
547
548                 BS_SETUP_PHASE(UNDEF)
549                 bs_hostque_delete(bsc, ti);
550                 if ((cb = ti->ti_ctab.tqh_first) != NULL)
551                 {
552                         if (bsc->sc_hstate == BSC_TARG_CHECK)
553                         {
554                                 ti->ti_error |= BSFATALIO;
555                                 bscmddone(ti);
556                         }
557                         else if (cb->rcnt >= bsc->sc_retry)
558                         {
559                                 ti->ti_error |= BSABNORMAL;
560                                 bscmddone(ti);
561                         }
562                         else if (ti->ti_error)
563                                 cb->rcnt++;
564                 }
565
566                 /* target state clear */
567                 BS_SETUP_PHASE(FREE)
568                 BS_SETUP_SYNCSTATE(BS_SYNCMSG_NULL);
569                 ti->ti_flags &= ~BSCFLAGSMASK;
570                 ti->ti_msgout = 0;
571 #ifdef  BS_DIAG
572                 ti->ti_flags &= ~BSNEXUS;
573 #endif  /* BS_DIAG */
574
575                 for ( ; cb; cb = cb->ccb_chain.tqe_next)
576                 {
577                         bs_kill_msg(cb);
578                         cb->bsccb_flags &= ~(BSITSDONE | BSCASTAT);
579                         cb->error = 0;
580                 }
581
582                 if (bsc->sc_hstate != BSC_TARG_CHECK &&
583                     ti->ti_bctab.tqh_first == NULL)
584                         ti->ti_bctab = ti->ti_ctab;
585
586                 TAILQ_INIT(&ti->ti_ctab);
587         }
588
589         if (bsc->sc_hstate != BSC_TARG_CHECK)
590                 bs_scsibus_start(bsc);
591 }
592
593 /**************************************************
594  * CHECK TARGETS AND START TARGETS
595  *************************************************/
596 static int
597 bs_start_target(ti)
598         struct targ_info *ti;
599 {
600         struct bsccb *cb;
601         struct scsi_start_stop_unit cmd;
602
603         bzero(&cmd, sizeof(struct scsi_start_stop_unit));
604         cmd.opcode = START_STOP;
605         cmd.how = SSS_START;
606         ti->ti_lun = 0;
607         cb = bs_make_internal_ccb(ti, 0, (u_int8_t *) &cmd,
608                                    sizeof(struct scsi_start_stop_unit),
609                                    NULL, 0, BSFORCEIOPOLL, BS_MOTOR_TIMEOUT);
610         bscmdstart(ti, BSCMDSTART);
611         return bs_scsi_cmd_poll(ti, cb);
612 }
613
614 /* test unit ready and check ATN msgout response */
615 static int
616 bs_check_target(ti)
617         struct targ_info *ti;
618 {
619         struct bs_softc *bsc = ti->ti_bsc;
620         struct scsi_inquiry scsi_cmd;
621         struct scsi_inquiry_data scsi_inquiry_data;
622         struct bsccb *cb;
623         int count, retry = bsc->sc_retry;
624         int s, error = COMPLETE;
625
626         ti->ti_lun = 0;
627         bsc->sc_retry = 2;
628         s = splbio();
629
630         /* inquiry */
631         bzero(&scsi_cmd, sizeof(scsi_cmd));
632         scsi_cmd.opcode = INQUIRY;
633         scsi_cmd.length = sizeof(struct scsi_inquiry_data);
634         cb = bs_make_internal_ccb(ti, 0,
635                                    (u_int8_t *) &scsi_cmd, sizeof(scsi_cmd),
636                                    (u_int8_t *) &scsi_inquiry_data,
637                                    sizeof(scsi_inquiry_data),
638                                    BSFORCEIOPOLL, BS_STARTUP_TIMEOUT);
639         bscmdstart(ti, BSCMDSTART);
640         error = bs_scsi_cmd_poll(ti, cb);
641         if (error != COMPLETE || (ti->ti_error & BSSELTIMEOUT))
642                 goto done;
643         ti->targ_type = scsi_inquiry_data.device;
644         ti->targ_support = scsi_inquiry_data.flags;
645
646         /* test unit ready twice */
647         for (count = 0; count < 2; count++)
648         {
649                 cb = bs_make_internal_ccb(ti, 0, NULL, 0, NULL, 0,
650                                          BSFORCEIOPOLL, BS_STARTUP_TIMEOUT);
651                 bscmdstart(ti, BSCMDSTART);
652                 error = bs_scsi_cmd_poll(ti, cb);
653                 if (error != COMPLETE || (ti->ti_error & BSSELTIMEOUT))
654                         goto done;
655         }
656
657         if (cb->bsccb_flags & BSCASTAT)
658                 bs_printf(ti, "check", "could not clear CA state");
659         ti->ti_error = 0;
660
661 done:
662         bsc->sc_retry = retry;
663
664         if (ti->ti_error & BSSELTIMEOUT)
665                 error = NOTARGET;
666
667         if (error == COMPLETE)
668                 error = bs_start_target(ti);
669
670         splx(s);
671         return error;
672 }
673
674 /**************************************************
675  * TARGET CONTROL
676  **************************************************/
677 struct targ_info *
678 bs_init_target_info(bsc, target)
679         struct bs_softc *bsc;
680         int target;
681 {
682         struct targ_info *ti;
683
684         ti = malloc(sizeof(struct targ_info), M_DEVBUF, M_NOWAIT);
685         if (ti == NULL)
686         {
687                 bs_printf(NULL, "bs_init_targ_info", "no target info memory");
688                 return ti;
689         }
690
691         bzero(ti, sizeof(*ti));
692
693         ti->ti_bsc = bsc;
694         ti->ti_id = target;
695         ti->sm_offset = 0;
696         ti->ti_cfgflags = BS_SCSI_NOPARITY | BS_SCSI_NOSAT;
697         ti->ti_mflags = ~(BSSAT | BSDISC | BSSMIT | BSLINK);
698         BS_SETUP_TARGSTATE(BS_TARG_CTRL);
699
700         TAILQ_INIT(&ti->ti_ctab);
701
702         bs_alloc_buf(ti);
703         if (ti->bounce_addr == NULL)
704         {
705                 free(ti, M_DEVBUF);
706                 return NULL;
707         }
708
709         TAILQ_INSERT_TAIL(&bsc->sc_titab, ti, ti_tchain);
710         bsc->sc_ti[target] = ti;
711         bsc->sc_openf |= (1 << target);
712
713         return ti;
714 }
715
716 void
717 bs_setup_ctrl(ti, quirks, flags)
718         struct targ_info *ti;
719         u_int quirks;
720         u_int flags;
721 {
722         struct bs_softc *bsc = ti->ti_bsc;
723         u_int offset, period, maxperiod;
724
725         if (ti->ti_state == BS_TARG_CTRL)
726         {
727                 ti->ti_cfgflags = BS_SCSI_POSITIVE;
728                 ti->ti_syncmax.offset = BSHW_MAX_OFFSET;
729                 BS_SETUP_TARGSTATE(BS_TARG_START);
730         }
731         else
732                 flags |= ti->ti_cfgflags & BS_SCSI_NEGATIVE;
733
734 #ifdef  BS_TARG_SAFEMODE
735         if (ti->targ_type != 0)
736         {
737                 flags &= ~(BS_SCSI_DISC | BS_SCSI_SYNC);
738                 flags |= BS_SCSI_NOPARITY;
739         }
740 #endif
741
742 #ifdef  SDEV_NODISC
743         if (quirks & SDEV_NODISC)
744                 flags &= ~BS_SCSI_DISC;
745 #endif
746 #ifdef  SDEV_NOPARITY
747         if (quirks & SDEV_NOPARITY)
748                 flags |= BS_SCSI_NOPARITY;
749 #endif
750 #ifdef  SDEV_NOCMDLNK
751         if (quirks & SDEV_NOCMDLNK)
752                 flags &= ~BS_SCSI_LINK;
753 #endif
754 #ifdef  SDEV_ASYNC
755         if (quirks & SDEV_ASYNC)
756                 flags &= ~BS_SCSI_SYNC;
757 #endif
758 #ifdef  SDEV_AUTOSAVE
759         if (quirks & SDEV_AUTOSAVE)
760                 flags |= BS_SCSI_SAVESP;
761 #endif
762 #ifdef  SD_Q_NO_SYNC
763         if (quirks & SD_Q_NO_SYNC)
764                 flags &= ~BS_SCSI_SYNC;
765 #endif
766
767         if ((flags & BS_SCSI_DISC) == 0 ||
768             (ti->targ_support & SID_Linked) == 0)
769                 flags &= ~BS_SCSI_LINK;
770
771         ti->sm_offset = (flags & BS_SCSI_NOSMIT) ?  0 : bsc->sm_offset;
772         if (ti->sm_offset == 0)
773                 flags |= BS_SCSI_NOSMIT;
774         else if (bsc->sc_cfgflags & BSC_SMITSAT_DISEN)
775                 flags |= BS_SCSI_NOSAT;
776
777         flags &= (ti->ti_cfgflags & BS_SCSI_POSITIVE) | (~BS_SCSI_POSITIVE);
778         ti->ti_cfgflags = flags;
779
780         /* calculate synch setup */
781         period = BS_SCSI_PERIOD(flags);
782         offset = (flags & BS_SCSI_SYNC) ? BS_SCSI_OFFSET(flags) : 0;
783
784         maxperiod = (bsc->sc_cspeed & IDR_FS_15_20) ? 100 : 50;
785         if (period > maxperiod)
786                 period = maxperiod;
787
788         if (period)
789                 period = 2500 / period;
790
791         if (ti->ti_syncmax.offset > offset)
792                 ti->ti_syncmax.offset = offset;
793         if (ti->ti_syncmax.period < period)
794                 ti->ti_syncmax.period = period;
795
796         bshw_adj_syncdata(&ti->ti_syncmax);
797
798         /* finally report our info */
799         printf("%s(%d:%d): {%d:0x%x:0x%x:%s} flags 0x%b\n",
800                 bsc->sc_dvname, ti->ti_id, ti->ti_lun,
801                (u_int) ti->targ_type,
802                (u_int) ti->targ_support,
803                (u_int) ti->bounce_size,
804                (flags & BS_SCSI_NOSMIT) ? "dma" : "pdma",
805                 flags, BS_SCSI_BITS);
806
807         /* internal representation */
808         ti->ti_mflags = ~0;
809         if ((ti->ti_cfgflags & BS_SCSI_DISC) == 0)
810                 ti->ti_mflags &= ~BSDISC;
811         if ((ti->ti_cfgflags & BS_SCSI_LINK) == 0)
812                 ti->ti_mflags &= ~BSLINK;
813         if (ti->ti_cfgflags & BS_SCSI_NOSAT)
814                 ti->ti_mflags &= ~BSSAT;
815         if (ti->ti_cfgflags & BS_SCSI_NOSMIT)
816                 ti->ti_mflags &= ~BSSMIT;
817 }
818
819 /**************************************************
820  * MISC
821  **************************************************/
822 void
823 bs_printf(ti, ph, c)
824         struct targ_info *ti;
825         char *ph;
826         char *c;
827 {
828
829         if (ti)
830                 printf("%s(%d:%d): <%s> %s\n",
831                        ti->ti_bsc->sc_dvname, ti->ti_id, ti->ti_lun, ph, c);
832         else
833                 printf("bs*(*:*): <%s> %s\n", ph, c);
834 }
835
836 void
837 bs_panic(bsc, c)
838         struct bs_softc *bsc;
839         u_char *c;
840 {
841
842         panic("%s %s\n", bsc->sc_dvname, c);
843 }
844
845 /**************************************************
846  * DEBUG FUNC
847  **************************************************/
848 #ifdef  BS_DEBUG_ROUTINE
849 u_int
850 bsr(addr)
851         u_int addr;
852 {
853
854         outb(0xcc0, addr);
855         return inb(0xcc2);
856 }
857
858 u_int
859 bsw(addr, data)
860         u_int addr;
861         int data;
862 {
863
864         outb(0xcc0, addr);
865         outb(0xcc2, data);
866         return 0;
867 }
868 #endif  /* BS_DEBUG_ROUTINE */
869
870 void
871 bs_debug_print_all(bsc)
872         struct bs_softc *bsc;
873 {
874         struct targ_info *ti;
875
876         for (ti = bsc->sc_titab.tqh_first; ti; ti = ti->ti_tchain.tqe_next)
877                 bs_debug_print(bsc, ti);
878 }
879
880 static u_char *phase[] =
881 {
882         "FREE", "HOSTQUE", "DISC", "COMPMSG", "ATN", "DISCMSG", "SELECT",
883         "SELECTED", "RESELECTED", "MSGIN", "MSGOUT", "STATIN", "CMDOUT",
884         "DATA", "SATSEL", "SATRESEL", "SATSDP", "SATCOMPSEQ", "UNDEF",
885 };
886
887 void
888 bs_debug_print(bsc, ti)
889         struct bs_softc *bsc;
890         struct targ_info *ti;
891 {
892         struct bsccb *cb;
893
894         /* host stat */
895         printf("%s <DEBUG INFO> nexus %lx bs %lx bus status %lx \n",
896                bsc->sc_dvname, (u_long) ti, (u_long) bsc->sc_nexus, (u_long) bsc->sc_busstat);
897
898         /* target stat */
899         if (ti)
900         {
901                 struct sc_p *sp = &bsc->sc_p;
902
903                 printf("%s(%d:%d) ph<%s> ", bsc->sc_dvname, ti->ti_id,
904                        ti->ti_lun, phase[(int) ti->ti_phase]);
905                 printf("msgptr %x msg[0] %x status %x tqh %lx fl %x\n",
906                        (u_int) (ti->ti_msginptr), (u_int) (ti->ti_msgin[0]),
907                        ti->ti_status, (u_long) (cb = ti->ti_ctab.tqh_first),
908                        ti->ti_flags);
909                 if (cb)
910                         printf("cmdlen %x cmdaddr %lx cmd[0] %x\n",
911                                cb->cmdlen, (u_long) cb->cmd, (int) cb->cmd[0]);
912                 printf("datalen %x dataaddr %lx seglen %x ",
913                        sp->datalen, (u_long) sp->data, sp->seglen);
914                 if (cb)
915                         printf("odatalen %x flags %x\n",
916                                 cb->datalen, cb->bsccb_flags);
917                 else
918                         printf("\n");
919                 printf("error flags %b\n", ti->ti_error, BSERRORBITS);
920         }
921 }