Change (almost) all references to tqh_first and tqe_next and tqe_prev
[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.7 2004/08/02 13:22:32 joerg 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 #if defined(__DragonFly__) || defined(__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 (struct targ_info *, char*);
55 static void bs_timeout_target (struct targ_info *);
56 static void bs_kill_msg (struct bsccb *cb);
57
58 static int bs_start_target (struct targ_info *);
59 static int bs_check_target (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 = TAILQ_FIRST(&ti->ti_ctab)))
100         {
101                 if ((cb->tc -= BS_TIMEOUT_CHECK_INTERVAL) < 0)
102                         bs_timeout_target(ti);
103         }
104         else {
105                 TAILQ_FOREACH(ti, &bsc->sc_titab, ti_tichain) {
106                         if (bsc->sc_dtgnum && ti->ti_phase < DISCONNECTED)
107                                 continue;
108
109                         cb = TAILQ_FIRST(&ti->ti_ctab);
110                         if (cb && ((cb->tc -= BS_TIMEOUT_CHECK_INTERVAL) < 0))
111                                 bs_timeout_target(ti);
112                 }
113         }
114
115         /* try to recover */
116         if (bsc->sc_flags & BSRESET)
117         {
118                 bs_debug_print_all(bsc);
119                 bs_printf(ti, "timeout", "bus hang up");
120                 bs_reset_nexus(bsc);
121         }
122
123         bs_start_timeout(bsc);
124         splx(s);
125 }
126
127 /**************************************************
128  * MAKE CCB & MSG CCB
129  *************************************************/
130 static u_int8_t cmd_unit_ready[6];
131
132 struct bsccb *
133 bs_make_internal_ccb(ti, lun, cmd, cmdlen, data, datalen, flags, timeout)
134         struct targ_info *ti;
135         u_int lun;
136         u_int8_t *cmd;
137         u_int cmdlen;
138         u_int8_t *data;
139         u_int datalen;
140         u_int flags;
141         int timeout;
142 {
143         struct bsccb *cb;
144
145         if ((cb = bs_get_ccb()) == NULL)
146                 bs_panic(ti->ti_bsc, "can not get ccb mem");
147
148         cb->ccb = NULL;
149         cb->lun = lun;
150         cb->cmd = (cmd ? cmd : cmd_unit_ready);
151         cb->cmdlen = (cmd ? cmdlen : sizeof(cmd_unit_ready));
152         cb->data = data;
153         cb->datalen = (data ? datalen : 0);
154         cb->msgoutlen = 0;
155         cb->bsccb_flags = flags & BSCFLAGSMASK;
156         bs_targ_flags(ti, cb);
157         cb->rcnt = 0;
158         cb->tcmax = (timeout > BS_DEFAULT_TIMEOUT_SECOND ? timeout :
159                                 BS_DEFAULT_TIMEOUT_SECOND);
160
161         TAILQ_INSERT_HEAD(&ti->ti_ctab, cb, ccb_chain);
162
163         return cb;
164 }
165
166 struct bsccb *
167 bs_make_msg_ccb(ti, lun, cb, msg, timex)
168         struct targ_info *ti;
169         u_int lun;
170         struct bsccb *cb;
171         struct msgbase *msg;
172         u_int timex;
173 {
174         u_int flags;
175
176         flags = BSFORCEIOPOLL | msg->flag;
177         if (cb == NULL)
178                 cb = bs_make_internal_ccb(ti, lun, NULL, 0, NULL, 0,
179                                            flags, timex);
180         else
181                 cb->bsccb_flags |= flags & BSCFLAGSMASK;
182
183         cb->msgoutlen = msg->msglen;
184         bcopy(msg->msg, cb->msgout, msg->msglen);
185         return cb;
186 }
187
188 int
189 bs_send_msg(ti, lun, msg, timex)
190         struct targ_info *ti;
191         u_int lun;
192         struct msgbase *msg;
193         int timex;
194 {
195         struct bsccb *cb;
196
197         cb = bs_make_msg_ccb(ti, lun, NULL, msg, timex);
198         bscmdstart(ti, BSCMDSTART);
199         return bs_scsi_cmd_poll(ti, cb);
200 }
201
202 static void
203 bs_kill_msg(cb)
204         struct bsccb *cb;
205 {
206         cb->msgoutlen = 0;
207 }
208
209 /**************************************************
210  * MAKE SENSE CCB
211  **************************************************/
212 struct bsccb *
213 bs_request_sense(ti)
214         struct targ_info *ti;
215 {
216         struct bsccb *cb;
217
218         bzero(ti->scsi_cmd, sizeof(struct scsi_sense));
219         bzero(&ti->sense, sizeof(struct scsi_sense_data));
220         ti->scsi_cmd[0] = REQUEST_SENSE;
221         ti->scsi_cmd[1] = (ti->ti_lun << 5);
222         ti->scsi_cmd[4] = sizeof(struct scsi_sense_data);
223         cb = bs_make_internal_ccb(ti, ti->ti_lun, ti->scsi_cmd,
224                                      sizeof(struct scsi_sense),
225                                      (u_int8_t *) & ti->sense,
226                                      sizeof(struct scsi_sense_data),
227                                      BSFORCEIOPOLL,
228                                      BS_DEFAULT_TIMEOUT_SECOND);
229         cb->bsccb_flags |= BSSENSECCB;
230         return cb;
231 }
232
233 /**************************************************
234  * SYNC MSG
235  *************************************************/
236 /* sync neg */
237 int
238 bs_start_syncmsg(ti, cb, flag)
239         struct targ_info *ti;
240         struct bsccb *cb;
241         int flag;
242 {
243         struct syncdata *negp, *maxp;
244         struct msgbase msg;
245         u_int lun;
246
247         negp = &ti->ti_syncnow;
248         maxp = &ti->ti_syncmax;
249
250         ti->ti_state = BS_TARG_SYNCH;
251
252         if (flag == BS_SYNCMSG_REQUESTED)
253         {
254                 if (negp->offset > maxp->offset)
255                         negp->offset = maxp->offset;
256                 if (negp->offset != 0 && negp->period < maxp->period)
257                         negp->period = maxp->period;
258
259                 msg.flag = 0;
260                 lun = ti->ti_lun;
261                 if (cb == NULL)
262                         cb = TAILQ_FIRST(&ti->ti_ctab);
263         }
264         else if (ti->ti_cfgflags & BS_SCSI_SYNC)
265         {
266                 negp->offset = maxp->offset;
267                 negp->period = maxp->period;
268
269                 msg.flag = BSERROROK;
270                 lun = 0;
271         }
272         else
273         {
274                 ti->ti_state = BS_TARG_RDY;
275                 return COMPLETE;
276         }
277
278         BS_SETUP_SYNCSTATE(flag);
279         msg.msg[0] = MSG_EXTEND;
280         msg.msg[1] = MSG_EXTEND_SYNCHLEN;
281         msg.msg[2] = MSG_EXTEND_SYNCHCODE;
282         msg.msg[3] = negp->period;
283         msg.msg[4] = negp->offset;
284         msg.msglen = MSG_EXTEND_SYNCHLEN + 2;
285
286         bs_make_msg_ccb(ti, lun, cb, &msg, BS_SYNC_TIMEOUT);
287         return COMPLETE;
288 }
289
290 static void
291 bs_print_syncmsg(ti, s)
292         struct targ_info *ti;
293         char *s;
294 {
295         struct bs_softc *bsc = ti->ti_bsc;
296         struct syncdata *negp;
297         u_int speed;
298
299         negp = &ti->ti_syncnow;
300         speed = (negp->offset && negp->period) ?
301                 (2500 / ((u_int) negp->period)) : 0;
302
303         printf("%s(%d:%d): <%s> ", bsc->sc_dvname, ti->ti_id, ti->ti_lun, s);
304         printf("period 0x%x offset %d chip (0x%x)", negp->period, negp->offset,
305                 ti->ti_sync);
306         if (speed)
307                 printf(" %d.%d M/s", speed / 10, speed % 10);
308         printf("\n");
309 }
310
311 int
312 bs_analyze_syncmsg(ti, cb)
313         struct targ_info *ti;
314         struct bsccb *cb;
315 {
316         struct bs_softc *bsc = ti->ti_bsc;
317         u_int8_t ans = ti->ti_syncnow.state;
318         struct syncdata *negp, *maxp;
319         struct syncdata bdata;
320         char *s = NULL;
321         u_int8_t period;
322
323         negp = &ti->ti_syncnow;
324         bdata = *negp;
325         maxp = &ti->ti_syncmax;
326
327         switch(ans)
328         {
329         case BS_SYNCMSG_REJECT:
330                 period = 0;
331                 s = "msg reject";
332                 break;
333
334         case BS_SYNCMSG_ASSERT:
335                 period = 0;
336                 s = "no msg";
337                 break;
338
339         default:
340                 if (negp->offset != 0 && negp->period < maxp->period)
341                 {
342                         period = 0xff;
343                         s = "illegal(period)";
344                 }
345                 else if (negp->offset > maxp->offset)
346                 {
347                         period = 0xff;
348                         s = "illegal(offset)";
349                 }
350                 else
351                         period = negp->offset ? negp->period : 0;
352                 break;
353         }
354
355         if (s == NULL)
356         {
357                 bshw_adj_syncdata(negp);
358                 *maxp = *negp;
359
360                 if (ans == BS_SYNCMSG_REQUESTED)
361                         s = "requested";
362                 else
363                         s = negp->offset ? "synchronous" : "async";
364         }
365         else
366         {
367                 negp->offset = maxp->offset = 0;
368                 bshw_adj_syncdata(negp);
369                 bshw_adj_syncdata(maxp);
370         }
371
372         /* really setup hardware */
373         bshw_set_synchronous(bsc, ti);
374         if (cb == NULL || (period >= negp->period && period <= negp->period + 2))
375         {
376                 bs_print_syncmsg(ti, s);
377                 BS_SETUP_TARGSTATE(BS_TARG_RDY);
378                 BS_SETUP_SYNCSTATE(BS_SYNCMSG_NULL);
379                 if (cb)
380                         bs_kill_msg(cb);
381
382                 return 0;
383         }
384         else
385         {
386                 bs_printf(ti, "bs_analyze_syncmsg",
387                           "sync(period) mismatch, retry neg...");
388                 printf("expect(%d:0x%x) => reply(%d:0x%x)\n",
389                         bdata.offset, bdata.period, negp->offset, negp->period);
390
391                 bs_start_syncmsg(ti, cb, BS_SYNCMSG_ASSERT);
392                 return EINVAL;
393         }
394 }
395
396 /**************************************************
397  * ABORT AND RESET MSG
398  **************************************************/
399 /* send device reset msg and wait */
400 void
401 bs_reset_device(ti)
402         struct targ_info *ti;
403 {
404         struct msgbase msg;
405
406         msg.msglen = 1;
407         msg.msg[0] = MSG_RESET;
408         msg.flag = 0;
409
410         bs_send_msg(ti, 0, &msg, 0);
411
412         delay(ti->ti_bsc->sc_RSTdelay);
413         bs_check_target(ti);
414 }
415
416 /* send abort msg */
417 struct bsccb *
418 bs_force_abort(ti)
419         struct targ_info *ti;
420 {
421         struct bs_softc *bsc = ti->ti_bsc;
422         struct msgbase msg;
423         struct bsccb *cb = TAILQ_FIRST(&ti->ti_ctab);
424         u_int lun;
425
426         if (cb)
427         {
428                 lun = cb->lun;
429                 cb->rcnt++;
430         }
431         else
432                 lun = 0;
433
434         msg.msglen = 1;
435         msg.msg[0] = MSG_ABORT;
436         msg.flag = 0;
437
438         cb = bs_make_msg_ccb(ti, lun, NULL, &msg, 0);
439         bscmdstart(ti, BSCMDSTART);
440
441         if (bsc->sc_nexus == ti)
442                 BS_LOAD_SDP
443
444         return cb;
445 }
446
447 /**************************************************
448  * COMPLETE SCSI BUS RESET
449  *************************************************/
450 /*
451  * XXX:
452  * 1) reset scsi bus (ie. all target reseted).
453  * 2) chip reset.
454  * 3) check target status.
455  * 4) sync neg with all targets.
456  * 5) setup sync reg in host.
457  * 6) recover previous nexus.
458  */
459 void
460 bs_scsibus_start(bsc)
461         struct bs_softc *bsc;
462 {
463         struct targ_info *ti, *nextti = NULL;
464         int error = HASERROR;
465         u_int querm, bits, skip = 0;
466
467         querm = (bsc->sc_hstate == BSC_BOOTUP);
468         bsc->sc_hstate = BSC_TARG_CHECK;
469
470         /* target check */
471         do
472         {
473                 if (error != COMPLETE)
474                 {
475                         printf("%s: scsi bus reset and try to restart ...",
476                                bsc->sc_dvname);
477                         bshw_smitabort(bsc);
478                         bshw_dmaabort(bsc, NULL);
479                         bshw_chip_reset(bsc);
480                         bshw_bus_reset(bsc);
481                         bshw_chip_reset(bsc);
482                         printf(" done. scsi bus ready.\n");
483                         nextti = TAILQ_FIRST(&bsc->sc_titab);
484                         error = COMPLETE;
485                 }
486
487                 if ((ti = nextti) == NULL)
488                         break;
489                 nextti = TAILQ_NEXT(ti, ti_tchain);
490
491                 bits = (1 << ti->ti_id);
492                 if (skip & bits)
493                         continue;
494
495                 if ((error = bs_check_target(ti)) != COMPLETE)
496                 {
497                         if (querm)
498                         {
499                                 TAILQ_REMOVE(&bsc->sc_titab, ti, ti_tchain);
500                                 bsc->sc_openf &= ~bits;
501                         }
502
503                         if (error == NOTARGET)
504                                 error = COMPLETE;
505
506                         skip |= bits;
507                 }
508         }
509         while (1);
510
511         /* ok now ready */
512         bsc->sc_hstate = BSC_RDY;
513
514         /* recover */
515         TAILQ_FOREACH(ti, &bsc->sc_titab; ti_tchain) {
516                 ti->ti_ctab = ti->ti_bctab;
517                 TAILQ_INIT(&ti->ti_bctab);
518                 if (!TAILQ_EMPTY(&ti->ti_ctab))
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         TAILQ_FOREACH(ti, &bsc->sc_titab, ti_tchain) {
544                 if (ti->ti_state == BS_TARG_SYNCH)
545                         bs_analyze_syncmsg(ti, NULL);
546                 if (ti->ti_state > BS_TARG_START)
547                         BS_SETUP_TARGSTATE(BS_TARG_START);
548
549                 BS_SETUP_PHASE(UNDEF)
550                 bs_hostque_delete(bsc, ti);
551                 if (!TAILQ_EMPTY(&ti->ti_ctab))
552                 {
553                         cb = TAILQ_FIRST(&ti->ti_ctab);
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                 TAILQ_FOREACH(cb, &ti->ti_ctab, ccb_chain) {
578                         bs_kill_msg(cb);
579                         cb->bsccb_flags &= ~(BSITSDONE | BSCASTAT);
580                         cb->error = 0;
581                 }
582
583                 if (bsc->sc_hstate != BSC_TARG_CHECK &&
584                     TAILQ_EMPTY(&ti->ti_bctab))
585                         ti->ti_bctab = ti->ti_ctab;
586
587                 TAILQ_INIT(&ti->ti_ctab);
588         }
589
590         if (bsc->sc_hstate != BSC_TARG_CHECK)
591                 bs_scsibus_start(bsc);
592 }
593
594 /**************************************************
595  * CHECK TARGETS AND START TARGETS
596  *************************************************/
597 static int
598 bs_start_target(ti)
599         struct targ_info *ti;
600 {
601         struct bsccb *cb;
602         struct scsi_start_stop_unit cmd;
603
604         bzero(&cmd, sizeof(struct scsi_start_stop_unit));
605         cmd.opcode = START_STOP;
606         cmd.how = SSS_START;
607         ti->ti_lun = 0;
608         cb = bs_make_internal_ccb(ti, 0, (u_int8_t *) &cmd,
609                                    sizeof(struct scsi_start_stop_unit),
610                                    NULL, 0, BSFORCEIOPOLL, BS_MOTOR_TIMEOUT);
611         bscmdstart(ti, BSCMDSTART);
612         return bs_scsi_cmd_poll(ti, cb);
613 }
614
615 /* test unit ready and check ATN msgout response */
616 static int
617 bs_check_target(ti)
618         struct targ_info *ti;
619 {
620         struct bs_softc *bsc = ti->ti_bsc;
621         struct scsi_inquiry scsi_cmd;
622         struct scsi_inquiry_data scsi_inquiry_data;
623         struct bsccb *cb;
624         int count, retry = bsc->sc_retry;
625         int s, error = COMPLETE;
626
627         ti->ti_lun = 0;
628         bsc->sc_retry = 2;
629         s = splcam();
630
631         /* inquiry */
632         bzero(&scsi_cmd, sizeof(scsi_cmd));
633         scsi_cmd.opcode = INQUIRY;
634         scsi_cmd.length = (u_int8_t) sizeof(struct scsi_inquiry_data);
635         cb = bs_make_internal_ccb(ti, 0,
636                                    (u_int8_t *) &scsi_cmd, sizeof(scsi_cmd),
637                                    (u_int8_t *) &scsi_inquiry_data,
638                                    sizeof(scsi_inquiry_data),
639                                    BSFORCEIOPOLL, BS_STARTUP_TIMEOUT);
640         bscmdstart(ti, BSCMDSTART);
641         error = bs_scsi_cmd_poll(ti, cb);
642         if (error != COMPLETE || (ti->ti_error & BSSELTIMEOUT))
643                 goto done;
644         ti->targ_type = scsi_inquiry_data.device;
645         ti->targ_support = scsi_inquiry_data.flags;
646
647         /* test unit ready twice */
648         for (count = 0; count < 2; count++)
649         {
650                 cb = bs_make_internal_ccb(ti, 0, NULL, 0, NULL, 0,
651                                          BSFORCEIOPOLL, BS_STARTUP_TIMEOUT);
652                 bscmdstart(ti, BSCMDSTART);
653                 error = bs_scsi_cmd_poll(ti, cb);
654                 if (error != COMPLETE || (ti->ti_error & BSSELTIMEOUT))
655                         goto done;
656         }
657
658         if (cb->bsccb_flags & BSCASTAT)
659                 bs_printf(ti, "check", "could not clear CA state");
660         ti->ti_error = 0;
661
662 done:
663         bsc->sc_retry = retry;
664
665         if (ti->ti_error & BSSELTIMEOUT)
666                 error = NOTARGET;
667
668         if (error == COMPLETE)
669                 error = bs_start_target(ti);
670
671         splx(s);
672         return error;
673 }
674
675 /**************************************************
676  * TARGET CONTROL
677  **************************************************/
678 struct targ_info *
679 bs_init_target_info(bsc, target)
680         struct bs_softc *bsc;
681         int target;
682 {
683         struct targ_info *ti;
684
685         ti = malloc(sizeof(struct targ_info), M_DEVBUF, M_WAITOK | M_ZERO);
686         ti->ti_bsc = bsc;
687         ti->ti_id = target;
688         ti->sm_offset = 0;
689         ti->ti_cfgflags = BS_SCSI_NOPARITY | BS_SCSI_NOSAT;
690         ti->ti_mflags = ~(BSSAT | BSDISC | BSSMIT | BSLINK);
691         BS_SETUP_TARGSTATE(BS_TARG_CTRL);
692
693         TAILQ_INIT(&ti->ti_ctab);
694
695         bs_alloc_buf(ti);
696         if (ti->bounce_addr == NULL)
697         {
698                 free(ti, M_DEVBUF);
699                 return NULL;
700         }
701
702         TAILQ_INSERT_TAIL(&bsc->sc_titab, ti, ti_tchain);
703         bsc->sc_ti[target] = ti;
704         bsc->sc_openf |= (1 << target);
705
706         return ti;
707 }
708
709 void
710 bs_setup_ctrl(ti, quirks, flags)
711         struct targ_info *ti;
712         u_int quirks;
713         u_int flags;
714 {
715         struct bs_softc *bsc = ti->ti_bsc;
716         u_int offset, period, maxperiod;
717
718         if (ti->ti_state == BS_TARG_CTRL)
719         {
720                 ti->ti_cfgflags = BS_SCSI_POSITIVE;
721                 ti->ti_syncmax.offset = BSHW_MAX_OFFSET;
722                 BS_SETUP_TARGSTATE(BS_TARG_START);
723         }
724         else
725                 flags |= ti->ti_cfgflags & BS_SCSI_NEGATIVE;
726
727 #ifdef  BS_TARG_SAFEMODE
728         if (ti->targ_type != 0)
729         {
730                 flags &= ~(BS_SCSI_DISC | BS_SCSI_SYNC);
731                 flags |= BS_SCSI_NOPARITY;
732         }
733 #endif
734
735 #ifdef  SDEV_NODISC
736         if (quirks & SDEV_NODISC)
737                 flags &= ~BS_SCSI_DISC;
738 #endif
739 #ifdef  SDEV_NOPARITY
740         if (quirks & SDEV_NOPARITY)
741                 flags |= BS_SCSI_NOPARITY;
742 #endif
743 #ifdef  SDEV_NOCMDLNK
744         if (quirks & SDEV_NOCMDLNK)
745                 flags &= ~BS_SCSI_LINK;
746 #endif
747 #ifdef  SDEV_ASYNC
748         if (quirks & SDEV_ASYNC)
749                 flags &= ~BS_SCSI_SYNC;
750 #endif
751 #ifdef  SDEV_AUTOSAVE
752         if (quirks & SDEV_AUTOSAVE)
753                 flags |= BS_SCSI_SAVESP;
754 #endif
755 #ifdef  SD_Q_NO_SYNC
756         if (quirks & SD_Q_NO_SYNC)
757                 flags &= ~BS_SCSI_SYNC;
758 #endif
759
760         if ((flags & BS_SCSI_DISC) == 0 ||
761             (ti->targ_support & SID_Linked) == 0)
762                 flags &= ~BS_SCSI_LINK;
763
764         ti->sm_offset = (flags & BS_SCSI_NOSMIT) ?  0 : bsc->sm_offset;
765         if (ti->sm_offset == 0)
766                 flags |= BS_SCSI_NOSMIT;
767         else if (bsc->sc_cfgflags & BSC_SMITSAT_DISEN)
768                 flags |= BS_SCSI_NOSAT;
769
770         flags &= (ti->ti_cfgflags & BS_SCSI_POSITIVE) | (~BS_SCSI_POSITIVE);
771         ti->ti_cfgflags = flags;
772
773         /* calculate synch setup */
774         period = BS_SCSI_PERIOD(flags);
775         offset = (flags & BS_SCSI_SYNC) ? BS_SCSI_OFFSET(flags) : 0;
776
777         maxperiod = (bsc->sc_cspeed & IDR_FS_16_20) ? 100 : 50;
778         if (period > maxperiod)
779                 period = maxperiod;
780
781         if (period)
782                 period = 2500 / period;
783
784         if (ti->ti_syncmax.offset > offset)
785                 ti->ti_syncmax.offset = offset;
786         if (ti->ti_syncmax.period < period)
787                 ti->ti_syncmax.period = period;
788
789         bshw_adj_syncdata(&ti->ti_syncmax);
790
791         /* finally report our info */
792         printf("%s(%d:%d): {%d:0x%x:0x%x:%s} flags 0x%b\n",
793                 bsc->sc_dvname, ti->ti_id, ti->ti_lun,
794                (u_int) ti->targ_type,
795                (u_int) ti->targ_support,
796                (u_int) ti->bounce_size,
797                (flags & BS_SCSI_NOSMIT) ? "dma" : "pdma",
798                 flags, BS_SCSI_BITS);
799
800         /* internal representation */
801         ti->ti_mflags = ~0;
802         if ((ti->ti_cfgflags & BS_SCSI_DISC) == 0)
803                 ti->ti_mflags &= ~BSDISC;
804         if ((ti->ti_cfgflags & BS_SCSI_LINK) == 0)
805                 ti->ti_mflags &= ~BSLINK;
806         if (ti->ti_cfgflags & BS_SCSI_NOSAT)
807                 ti->ti_mflags &= ~BSSAT;
808         if (ti->ti_cfgflags & BS_SCSI_NOSMIT)
809                 ti->ti_mflags &= ~BSSMIT;
810 }
811
812 /**************************************************
813  * MISC
814  **************************************************/
815 void
816 bs_printf(ti, ph, c)
817         struct targ_info *ti;
818         char *ph;
819         char *c;
820 {
821
822         if (ti)
823                 printf("%s(%d:%d): <%s> %s\n",
824                        ti->ti_bsc->sc_dvname, ti->ti_id, ti->ti_lun, ph, c);
825         else
826                 printf("bs*(*:*): <%s> %s\n", ph, c);
827 }
828
829 void
830 bs_panic(bsc, c)
831         struct bs_softc *bsc;
832         u_char *c;
833 {
834
835         panic("%s %s\n", bsc->sc_dvname, c);
836 }
837
838 /**************************************************
839  * DEBUG FUNC
840  **************************************************/
841 #ifdef  BS_DEBUG_ROUTINE
842 u_int
843 bsr(addr)
844         u_int addr;
845 {
846
847         outb(0xcc0, addr);
848         return inb(0xcc2);
849 }
850
851 u_int
852 bsw(addr, data)
853         u_int addr;
854         int data;
855 {
856
857         outb(0xcc0, addr);
858         outb(0xcc2, data);
859         return 0;
860 }
861 #endif  /* BS_DEBUG_ROUTINE */
862
863 void
864 bs_debug_print_all(bsc)
865         struct bs_softc *bsc;
866 {
867         struct targ_info *ti;
868
869         TAILQ_FOREACH(ti, &bsc->sc_titab.tqh_first, ti_tchain)
870                 bs_debug_print(bsc, ti);
871 }
872
873 static u_char *phase[] =
874 {
875         "FREE", "HOSTQUE", "DISC", "COMPMSG", "ATN", "DISCMSG", "SELECT",
876         "SELECTED", "RESELECTED", "MSGIN", "MSGOUT", "STATIN", "CMDOUT",
877         "DATA", "SATSEL", "SATRESEL", "SATSDP", "SATCOMPSEQ", "UNDEF",
878 };
879
880 void
881 bs_debug_print(bsc, ti)
882         struct bs_softc *bsc;
883         struct targ_info *ti;
884 {
885         struct bsccb *cb;
886
887         /* host stat */
888         printf("%s <DEBUG INFO> nexus %lx bs %lx bus status %lx \n",
889                bsc->sc_dvname, (u_long) ti, (u_long) bsc->sc_nexus, (u_long) bsc->sc_busstat);
890
891         /* target stat */
892         if (ti)
893         {
894                 struct sc_p *sp = &bsc->sc_p;
895
896                 printf("%s(%d:%d) ph<%s> ", bsc->sc_dvname, ti->ti_id,
897                        ti->ti_lun, phase[(int) ti->ti_phase]);
898                 printf("msgptr %x msg[0] %x status %x tqh %lx fl %x\n",
899                        (u_int) (ti->ti_msginptr), (u_int) (ti->ti_msgin[0]),
900                        ti->ti_status, (u_long) (cb = TAILQ_FIRST(&ti->ti_ctab)),
901                        ti->ti_flags);
902                 if (cb)
903                         printf("cmdlen %x cmdaddr %lx cmd[0] %x\n",
904                                cb->cmdlen, (u_long) cb->cmd, (int) cb->cmd[0]);
905                 printf("datalen %x dataaddr %lx seglen %x ",
906                        sp->datalen, (u_long) sp->data, sp->seglen);
907                 if (cb)
908                         printf("odatalen %x flags %x\n",
909                                 cb->datalen, cb->bsccb_flags);
910                 else
911                         printf("\n");
912                 printf("error flags %b\n", ti->ti_error, BSERRORBITS);
913         }
914 }