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