|
|
1.1 root 1: /*
2: * Written by Julian Elischer ([email protected])
3: * for TRW Financial Systems for use under the MACH(2.5) operating system.
4: *
5: * TRW Financial Systems, in accordance with their agreement with Carnegie
6: * Mellon University, makes this software available to CMU to distribute
7: * or use in any manner that they see fit as long as this message is kept with
8: * the software. For this reason TFS also grants any other persons or
9: * organisations permission to use or modify this software.
10: *
11: * TFS supplies this software to be publicly redistributed
12: * on the understanding that TFS is not responsible for the correct
13: * functioning of this software in any circumstances.
14: *
15: *
16: * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
17: * -------------------- ----- ----------------------
18: * CURRENT PATCH LEVEL: 1 00098
19: * -------------------- ----- ----------------------
20: *
21: * 16 Feb 93 Julian Elischer ADDED for SCSI system
22: */
23:
24: /*
25: * HISTORY
26: * $Log: bt742a.c,v $
27: * Revision 1.2 1993/04/10 12:05:14 glass
28: * fixed to be compliant, subservient, and to take advantage of the newly
29: * hacked config(8)
30: *
31: * Revision 1.1 1993/03/21 18:10:06 cgd
32: * after 0.2.2 "stable" patches applied
33: *
34: * Revision 1.7 1992/08/24 22:40:16 jason
35: * BIG_DMA ifdef for 512 dma segments instead of 128 segments
36: *
37: * Revision 1.6 1992/08/24 21:01:58 jason
38: * many changes and bugfixes for osf1
39: *
40: * Revision 1.5 1992/07/31 01:22:03 julian
41: * support improved scsi.h layout
42: *
43: * Revision 1.4 1992/07/25 03:11:26 julian
44: * check each request fro sane flags.
45: *
46: * Revision 1.3 1992/07/24 00:52:45 julian
47: * improved timeout handling.
48: * added support for two arguments to the sd_done (or equiv) call so that
49: * they can pre-queue several arguments.
50: * slightly clean up error handling
51: *
52: * Revision 1.2 1992/07/17 22:03:54 julian
53: * upgraded the timeout code.
54: * added support for UIO-based i/o (as used for pmem operations)
55: *
56: * Revision 1.1 1992/05/27 00:51:12 balsup
57: * machkern/cor merge
58: *
59: */
60:
61: /*
62: * bt742a BT-1542A SCSI driver
63: */
64:
65: #include <sys/types.h>
66: #include <bt.h>
67:
68: #include <sys/param.h>
69: #include <sys/systm.h>
70: #include <sys/errno.h>
71: #include <sys/ioctl.h>
72: #include <sys/buf.h>
73: #include <sys/proc.h>
74: #include <sys/user.h>
75:
76: #ifdef MACH /* EITHER CMU OR OSF */
77: #include <i386/ipl.h>
78: #include <i386at/scsi.h>
79: #include <i386at/scsiconf.h>
80:
81: #ifdef OSF /* OSF ONLY */
82: #include <sys/table.h>
83: #include <i386/handler.h>
84: #include <i386/dispatcher.h>
85: #include <i386/AT386/atbus.h>
86:
87: #else OSF /* CMU ONLY */
88: #include <i386at/atbus.h>
89: #include <i386/pio.h>
90: #endif OSF
91: #endif MACH /* end of MACH specific */
92:
93: #ifdef __386BSD__ /* 386BSD specific */
94: #define isa_dev isa_device
95: #define dev_unit id_unit
96: #define dev_addr id_iobase
97:
98: #include <i386/isa/isa_device.h>
99: #include <scsi/scsi_all.h>
100: #include <scsi/scsiconf.h>
101: #endif __386BSD__
102:
103:
104: #ifdef __386BSD__
105: #ifdef DDB
106: int Debugger();
107: #else
108: #define Debugger() panic("should call debugger here (adaptec.c)")
109: #endif /*!DDB*/
110: #endif __386BSD__
111:
112: #ifdef MACH
113: int Debugger();
114: #endif MACH
115:
116: extern int delaycount; /* from clock setup code */
117: typedef unsigned long int physaddr;
118:
119: /*
120: * I/O Port Interface
121: */
122:
123: #define BT_BASE bt_base[unit]
124: #define BT_CTRL_STAT_PORT (BT_BASE + 0x0) /* control & status */
125: #define BT_CMD_DATA_PORT (BT_BASE + 0x1) /* cmds and datas */
126: #define BT_INTR_PORT (BT_BASE + 0x2) /* Intr. stat */
127:
128: /*
129: * BT_CTRL_STAT bits (write)
130: */
131:
132: #define BT_HRST 0x80 /* Hardware reset */
133: #define BT_SRST 0x40 /* Software reset */
134: #define BT_IRST 0x20 /* Interrupt reset */
135: #define BT_SCRST 0x10 /* SCSI bus reset */
136:
137: /*
138: * BT_CTRL_STAT bits (read)
139: */
140:
141: #define BT_STST 0x80 /* Self test in Progress */
142: #define BT_DIAGF 0x40 /* Diagnostic Failure */
143: #define BT_INIT 0x20 /* Mbx Init required */
144: #define BT_IDLE 0x10 /* Host Adapter Idle */
145: #define BT_CDF 0x08 /* cmd/data out port full */
146: #define BT_DF 0x04 /* Data in port full */
147: #define BT_INVDCMD 0x01 /* Invalid command */
148:
149: /*
150: * BT_CMD_DATA bits (write)
151: */
152:
153: #define BT_NOP 0x00 /* No operation */
154: #define BT_MBX_INIT 0x01 /* Mbx initialization */
155: #define BT_START_SCSI 0x02 /* start scsi command */
156: #define BT_START_BIOS 0x03 /* start bios command */
157: #define BT_INQUIRE 0x04 /* Adapter Inquiry */
158: #define BT_MBO_INTR_EN 0x05 /* Enable MBO available interrupt */
159: #define BT_SEL_TIMEOUT_SET 0x06 /* set selection time-out */
160: #define BT_BUS_ON_TIME_SET 0x07 /* set bus-on time */
161: #define BT_BUS_OFF_TIME_SET 0x08 /* set bus-off time */
162: #define BT_SPEED_SET 0x09 /* set transfer speed */
163: #define BT_DEV_GET 0x0a /* return installed devices */
164: #define BT_CONF_GET 0x0b /* return configuration data */
165: #define BT_TARGET_EN 0x0c /* enable target mode */
166: #define BT_SETUP_GET 0x0d /* return setup data */
167: #define BT_WRITE_CH2 0x1a /* write channel 2 buffer */
168: #define BT_READ_CH2 0x1b /* read channel 2 buffer */
169: #define BT_WRITE_FIFO 0x1c /* write fifo buffer */
170: #define BT_READ_FIFO 0x1d /* read fifo buffer */
171: #define BT_ECHO 0x1e /* Echo command data */
172: #define BT_MBX_INIT_EXTENDED 0x81 /* Mbx initialization */
173: #define BT_INQUIRE_EXTENDED 0x8D /* Adapter Setup Inquiry */
174:
175: struct bt_cmd_buf {
176: u_char byte[16];
177: };
178:
179: /*
180: * BT_INTR_PORT bits (read)
181: */
182:
183: #define BT_ANY_INTR 0x80 /* Any interrupt */
184: #define BT_SCRD 0x08 /* SCSI reset detected */
185: #define BT_HACC 0x04 /* Command complete */
186: #define BT_MBOA 0x02 /* MBX out empty */
187: #define BT_MBIF 0x01 /* MBX in full */
188:
189: /*
190: * Mail box defs
191: */
192:
193: #define BT_MBX_SIZE 16 /* mail box size */
194:
195: struct bt_mbx
196: {
197: struct bt_mbx_out {
198: physaddr ccb_addr;
199: unsigned char dummy[3];
200: unsigned char cmd;
201: } mbo [BT_MBX_SIZE];
202: struct bt_mbx_in{
203: physaddr ccb_addr;
204: unsigned char btstat;
205: unsigned char sdstat;
206: unsigned char dummy;
207: unsigned char stat;
208: } mbi[BT_MBX_SIZE];
209: };
210:
211: /*
212: * mbo.cmd values
213: */
214:
215: #define BT_MBO_FREE 0x0 /* MBO entry is free */
216: #define BT_MBO_START 0x1 /* MBO activate entry */
217: #define BT_MBO_ABORT 0x2 /* MBO abort entry */
218:
219: #define BT_MBI_FREE 0x0 /* MBI entry is free */
220: #define BT_MBI_OK 0x1 /* completed without error */
221: #define BT_MBI_ABORT 0x2 /* aborted ccb */
222: #define BT_MBI_UNKNOWN 0x3 /* Tried to abort invalid CCB */
223: #define BT_MBI_ERROR 0x4 /* Completed with error */
224:
225: extern struct bt_mbx bt_mbx[];
226:
227: #if defined(BIG_DMA)
228: /* #define BT_NSEG 8192 /* Number of scatter gather segments - to much vm */
229: #define BT_NSEG 512
230: #else
231: #define BT_NSEG 33
232: #endif /* BIG_DMA */
233: struct bt_scat_gath
234: {
235: unsigned long seg_len;
236: physaddr seg_addr;
237: };
238:
239: struct bt_ccb {
240: unsigned char opcode;
241: unsigned char :3,data_in:1,data_out:1,:3;
242: unsigned char scsi_cmd_length;
243: unsigned char req_sense_length;
244: /*------------------------------------longword boundary */
245: unsigned long data_length;
246: /*------------------------------------longword boundary */
247: physaddr data_addr;
248: /*------------------------------------longword boundary */
249: unsigned char dummy[2];
250: unsigned char host_stat;
251: unsigned char target_stat;
252: /*------------------------------------longword boundary */
253: unsigned char target;
254: unsigned char lun;
255: unsigned char scsi_cmd[12]; /* 12 bytes (bytes only)*/
256: unsigned char dummy2[1];
257: unsigned char link_id;
258: /*------------------------------------4 longword boundary */
259: physaddr link_addr;
260: /*------------------------------------longword boundary */
261: physaddr sense_ptr;
262: /*------------------------------------longword boundary */
263: struct scsi_sense_data scsi_sense;
264: /*------------------------------------longword boundary */
265: struct bt_scat_gath scat_gath[BT_NSEG];
266: /*------------------------------------longword boundary */
267: struct bt_ccb *next;
268: /*------------------------------------longword boundary */
269: struct scsi_xfer *xfer; /* the scsi_xfer for this cmd */
270: /*------------------------------------longword boundary */
271: struct bt_mbx_out *mbx; /* pointer to mail box */
272: /*------------------------------------longword boundary */
273: long int delta; /* difference from previous*/
274: struct bt_ccb *later,*sooner;
275: int flags;
276: #define CCB_FREE 0
277: #define CCB_ACTIVE 1
278: #define CCB_ABORTED 2
279: };
280:
281: struct bt_ccb *bt_soonest = (struct bt_ccb *)0;
282: struct bt_ccb *bt_latest = (struct bt_ccb *)0;
283: long int bt_furtherest = 0; /* longest time in the timeout queue */
284: /*
285: * opcode fields
286: */
287:
288: #define BT_INITIATOR_CCB 0x00 /* SCSI Initiator CCB */
289: #define BT_TARGET_CCB 0x01 /* SCSI Target CCB */
290: #define BT_INIT_SCAT_GATH_CCB 0x02 /* SCSI Initiator with scattter gather*/
291: #define BT_RESET_CCB 0x81 /* SCSI Bus reset */
292:
293:
294: /*
295: * bt_ccb.host_stat values
296: */
297:
298: #define BT_OK 0x00 /* cmd ok */
299: #define BT_LINK_OK 0x0a /* Link cmd ok */
300: #define BT_LINK_IT 0x0b /* Link cmd ok + int */
301: #define BT_SEL_TIMEOUT 0x11 /* Selection time out */
302: #define BT_OVER_UNDER 0x12 /* Data over/under run */
303: #define BT_BUS_FREE 0x13 /* Bus dropped at unexpected time */
304: #define BT_INV_BUS 0x14 /* Invalid bus phase/sequence */
305: #define BT_BAD_MBO 0x15 /* Incorrect MBO cmd */
306: #define BT_BAD_CCB 0x16 /* Incorrect ccb opcode */
307: #define BT_BAD_LINK 0x17 /* Not same values of LUN for links */
308: #define BT_INV_TARGET 0x18 /* Invalid target direction */
309: #define BT_CCB_DUP 0x19 /* Duplicate CCB received */
310: #define BT_INV_CCB 0x1a /* Invalid CCB or segment list */
311: #define BT_ABORTED 42 /* pseudo value from driver */
312:
313:
314:
315: struct bt_setup
316: {
317: u_char sync_neg:1;
318: u_char parity:1;
319: u_char :6;
320: u_char speed;
321: u_char bus_on;
322: u_char bus_off;
323: u_char num_mbx;
324: u_char mbx[4];
325: struct
326: {
327: u_char offset:4;
328: u_char period:3;
329: u_char valid:1;
330: }sync[8];
331: u_char disc_sts;
332: };
333:
334: struct bt_config
335: {
336: u_char chan;
337: u_char intr;
338: u_char scsi_dev:3;
339: u_char :5;
340: };
341:
342: #define INT9 0x01
343: #define INT10 0x02
344: #define INT11 0x04
345: #define INT12 0x08
346: #define INT14 0x20
347: #define INT15 0x40
348:
349: #define EISADMA 0x00
350: #define CHAN0 0x01
351: #define CHAN5 0x20
352: #define CHAN6 0x40
353: #define CHAN7 0x80
354:
355:
356:
357:
358: #ifdef MACH
359: extern physaddr kvtophys();
360: #define PHYSTOKV(x) phystokv(x)
361: #define KVTOPHYS(x) kvtophys(x)
362: #endif MACH
363:
364: #ifdef __386BSD__
365: #define PHYSTOKV(x) (x | 0xFE000000)
366: #define KVTOPHYS(x) vtophys(x)
367: #endif __386BSD__
368:
369:
370:
371: #define PAGESIZ 4096
372: #define INVALIDATE_CACHE {asm volatile( ".byte 0x0F ;.byte 0x08" ); }
373:
374:
375: u_char bt_scratch_buf[256];
376: #ifdef MACH
377: caddr_t bt_base[NBT]; /* base port for each board */
378: #else MACH
379: short bt_base[NBT]; /* base port for each board */
380: #endif MACH
381: struct bt_mbx bt_mbx[NBT];
382: struct bt_ccb *bt_ccb_free[NBT];
383: struct bt_ccb bt_ccb[NBT][BT_MBX_SIZE];
384: struct scsi_xfer bt_scsi_xfer[NBT];
385: struct isa_dev *btinfo[NBT];
386: struct bt_ccb *bt_get_ccb();
387: int bt_int[NBT];
388: int bt_dma[NBT];
389: int bt_scsi_dev[NBT];
390: int bt_initialized[NBT];
391: #if defined(OSF)
392: int bt_attached[NBT];
393: #endif /* defined(OSF) */
394:
395: /***********debug values *************/
396: #define BT_SHOWCCBS 0x01
397: #define BT_SHOWINTS 0x02
398: #define BT_SHOWCMDS 0x04
399: #define BT_SHOWMISC 0x08
400: int bt_debug = 0;
401:
402:
403: int btprobe(), btattach();
404: int btintr();
405:
406: #ifdef MACH
407: struct isa_driver btdriver = { btprobe, 0, btattach, "bt", 0, 0, 0};
408: int (*btintrs[])() = {btintr, 0};
409: #endif MACH
410:
411: #ifdef __386BSD__
412: struct isa_driver btdriver = { btprobe, btattach, "bt"};
413: #endif __386BSD__
414:
415: static int btunit = 0;
416:
417: #define bt_abortmbx(mbx) \
418: (mbx)->cmd = BT_MBO_ABORT; \
419: outb(BT_CMD_DATA_PORT, BT_START_SCSI);
420: #define bt_startmbx(mbx) \
421: (mbx)->cmd = BT_MBO_START; \
422: outb(BT_CMD_DATA_PORT, BT_START_SCSI);
423:
424:
425:
426: int bt_scsi_cmd();
427: int bt_timeout();
428: void btminphys();
429: long int bt_adapter_info();
430:
431: struct scsi_switch bt_switch =
432: {
433: bt_scsi_cmd,
434: btminphys,
435: 0,
436: 0,
437: bt_adapter_info,
438: 0,0,0
439: };
440: #define BT_CMD_TIMEOUT_FUDGE 200 /* multiplied to get Secs */
441: #define BT_RESET_TIMEOUT 1000000
442: #define BT_SCSI_TIMEOUT_FUDGE 20 /* divided by for mSecs */
443:
444:
445: /***********************************************************************\
446: * bt_cmd(unit,icnt, ocnt,wait, retval, opcode, args) *
447: * Activate Adapter command *
448: * icnt: number of args (outbound bytes written after opcode) *
449: * ocnt: number of expected returned bytes *
450: * wait: number of seconds to wait for response *
451: * retval: buffer where to place returned bytes *
452: * opcode: opcode BT_NOP, BT_MBX_INIT, BT_START_SCSI ... *
453: * args: parameters *
454: * *
455: * Performs an adapter command through the ports. Not to be confused *
456: * with a scsi command, which is read in via the dma *
457: * One of the adapter commands tells it to read in a scsi command *
458: \***********************************************************************/
459: bt_cmd(unit,icnt, ocnt, wait,retval, opcode, args)
460:
461: u_char *retval;
462: unsigned opcode;
463: u_char args;
464: {
465: unsigned *ic = &opcode;
466: u_char oc;
467: register i;
468: int sts;
469:
470: /*******************************************************\
471: * multiply the wait argument by a big constant *
472: * zero defaults to 1 *
473: \*******************************************************/
474: if(!wait)
475: wait = BT_CMD_TIMEOUT_FUDGE * delaycount;
476: else
477: wait *= BT_CMD_TIMEOUT_FUDGE * delaycount;
478: /*******************************************************\
479: * Wait for the adapter to go idle, unless it's one of *
480: * the commands which don't need this *
481: \*******************************************************/
482: if (opcode != BT_MBX_INIT && opcode != BT_START_SCSI)
483: {
484: i = BT_CMD_TIMEOUT_FUDGE * delaycount; /* 1 sec?*/
485: while (--i)
486: {
487: sts = inb(BT_CTRL_STAT_PORT);
488: if (sts & BT_IDLE)
489: {
490: break;
491: }
492: }
493: if (!i)
494: {
495: printf("bt_cmd: bt742a host not idle(0x%x)\n",sts);
496: return(ENXIO);
497: }
498: }
499: /*******************************************************\
500: * Now that it is idle, if we expect output, preflush the*
501: * queue feeding to us. *
502: \*******************************************************/
503: if (ocnt)
504: {
505: while((inb(BT_CTRL_STAT_PORT)) & BT_DF)
506: inb(BT_CMD_DATA_PORT);
507: }
508:
509: /*******************************************************\
510: * Output the command and the number of arguments given *
511: * for each byte, first check the port is empty. *
512: \*******************************************************/
513: icnt++; /* include the command */
514: while (icnt--)
515: {
516: sts = inb(BT_CTRL_STAT_PORT);
517: for (i=0; i< wait; i++)
518: {
519: sts = inb(BT_CTRL_STAT_PORT);
520: if (!(sts & BT_CDF))
521: break;
522: }
523: if (i >= wait)
524: {
525: printf("bt_cmd: bt742a cmd/data port full\n");
526: outb(BT_CTRL_STAT_PORT, BT_SRST);
527: return(ENXIO);
528: }
529: outb(BT_CMD_DATA_PORT, (u_char)(*ic++));
530: }
531: /*******************************************************\
532: * If we expect input, loop that many times, each time, *
533: * looking for the data register to have valid data *
534: \*******************************************************/
535: while (ocnt--)
536: {
537: sts = inb(BT_CTRL_STAT_PORT);
538: for (i=0; i< wait; i++)
539: {
540: sts = inb(BT_CTRL_STAT_PORT);
541: if (sts & BT_DF)
542: break;
543: }
544: if (i >= wait)
545: {
546: printf("bt_cmd: bt742a cmd/data port empty %d\n",ocnt);
547: return(ENXIO);
548: }
549: oc = inb(BT_CMD_DATA_PORT);
550: if (retval)
551: *retval++ = oc;
552: }
553: /*******************************************************\
554: * Wait for the board to report a finised instruction *
555: \*******************************************************/
556: i=BT_CMD_TIMEOUT_FUDGE * delaycount; /* 1 sec? */
557: while (--i)
558: {
559: sts = inb(BT_INTR_PORT);
560: if (sts & BT_HACC)
561: {
562: break;
563: }
564: }
565: if (!i)
566: {
567: printf("bt_cmd: bt742a host not finished(0x%x)\n",sts);
568: return(ENXIO);
569: }
570: outb(BT_CTRL_STAT_PORT, BT_IRST);
571: return(0);
572: }
573:
574: /*******************************************************\
575: * Check if the device can be found at the port given *
576: * and if so, set it up ready for further work *
577: * as an argument, takes the isa_dev structure from *
578: * autoconf.c *
579: \*******************************************************/
580:
581: btprobe(dev)
582: struct isa_dev *dev;
583: {
584: /***********************************************\
585: * find unit and check we have that many defined *
586: \***********************************************/
587: int unit = btunit;
588: #if defined(OSF)
589: static ihandler_t bt_handler[NBT];
590: static ihandler_id_t *bt_handler_id[NBT];
591: register ihandler_t *chp = &bt_handler[unit];;
592: #endif /* defined(OSF) */
593:
594: dev->dev_unit = unit;
595: bt_base[unit] = dev->dev_addr;
596: if(unit >= NBT)
597: {
598: printf("bt: unit number (%d) too high\n",unit);
599: return(0);
600: }
601: /***********************************************\
602: * Try initialise a unit at this location *
603: * sets up dma and bus speed, loads bt_int[unit]*
604: \***********************************************/
605: if (bt_init(unit) != 0)
606: {
607: return(0);
608: }
609:
610: /***********************************************\
611: * If it's there, put in it's interrupt vectors *
612: \***********************************************/
613: #ifdef MACH
614: #if defined(OSF) /* OSF */
615: chp->ih_level = dev->dev_pic;
616: chp->ih_handler = dev->dev_intr[0];
617: chp->ih_resolver = i386_resolver;
618: chp->ih_rdev = dev;
619: chp->ih_stats.intr_type = INTR_DEVICE;
620: chp->ih_stats.intr_cnt = 0;
621: chp->ih_hparam[0].intparam = unit;
622: if ((bt_handler_id[unit] = handler_add(chp)) != NULL)
623: handler_enable(bt_handler_id[unit]);
624: else
625: panic("Unable to add bt interrupt handler");
626: #else /* CMU */
627: dev->dev_pic = bt_int[unit];
628: take_dev_irq(dev);
629: #endif /* !defined(OSF) */
630: printf("port=%x spl=%d\n", dev->dev_addr, dev->dev_spl);
631: #endif MACH
632: #ifdef __386BSD__ /* 386BSD */
633: dev->id_irq = (1 << bt_int[unit]);
634: dev->id_drq = bt_dma[unit];
635: printf("\n **");
636: #endif __386BSD__
637:
638: btunit++;
639: return(1);
640: }
641:
642: /***********************************************\
643: * Attach all the sub-devices we can find *
644: \***********************************************/
645: btattach(dev)
646: struct isa_dev *dev;
647: {
648: int unit = dev->dev_unit;
649:
650:
651: #ifdef __386BSD__
652: printf(" probing for scsi devices**\n");
653: #endif __386BSD__
654:
655: /***********************************************\
656: * ask the adapter what subunits are present *
657: \***********************************************/
658: scsi_attachdevs( unit, bt_scsi_dev[unit], &bt_switch);
659: #if defined(OSF)
660: bt_attached[unit]=1;
661: #endif /* defined(OSF) */
662: if(!unit) /* only one for all boards */
663: {
664: bt_timeout(0);
665: }
666: #ifdef __386BSD__
667: printf("bt%d",unit);
668: #endif __386BSD__
669: return;
670: }
671:
672: /***********************************************\
673: * Return some information to the caller about *
674: * the adapter and it's capabilities *
675: \***********************************************/
676: long int bt_adapter_info(unit)
677: int unit;
678: {
679: return(2); /* 2 outstanding requests at a time per device */
680: }
681:
682: /***********************************************\
683: * Catch an interrupt from the adaptor *
684: \***********************************************/
685: btintr(unit)
686: {
687: struct bt_ccb *ccb;
688: unsigned char stat;
689: register i;
690:
691: if(scsi_debug & PRINTROUTINES)
692: printf("btintr ");
693: /***********************************************\
694: * First acknowlege the interrupt, Then if it's *
695: * not telling about a completed operation *
696: * just return. *
697: \***********************************************/
698: stat = inb(BT_INTR_PORT);
699: outb(BT_CTRL_STAT_PORT, BT_IRST);
700: if(scsi_debug & TRACEINTERRUPTS)
701: printf("int = 0x%x ",stat);
702: if (! (stat & BT_MBIF))
703: return 1;
704: if(scsi_debug & TRACEINTERRUPTS)
705: printf("mbxi ");
706: #if defined(OSF)
707: if (!bt_attached[unit])
708: {
709: return(1);
710: }
711: #endif /* defined(OSF) */
712: /***********************************************\
713: * If it IS then process the competed operation *
714: \***********************************************/
715: for (i = 0; i < BT_MBX_SIZE; i++)
716: {
717: if (bt_mbx[unit].mbi[i].stat != BT_MBI_FREE)
718: {
719: ccb = (struct bt_ccb *)PHYSTOKV(
720: (bt_mbx[unit].mbi[i].ccb_addr));
721: if((bt_debug & BT_SHOWCCBS) && ccb)
722: printf("<int ccb(%x)>",ccb);
723: if((stat = bt_mbx[unit].mbi[i].stat) != BT_MBI_OK)
724: {
725: switch(stat)
726: {
727: case BT_MBI_ABORT:
728: if(bt_debug & BT_SHOWMISC)
729: printf("abort ");
730: ccb->host_stat = BT_ABORTED;
731: break;
732:
733: case BT_MBI_UNKNOWN:
734: ccb = (struct bt_ccb *)0;
735: if(bt_debug & BT_SHOWMISC)
736: printf("unknown ccb for abort");
737: break;
738:
739: case BT_MBI_ERROR:
740: break;
741:
742: default:
743: panic("Impossible mbxi status");
744:
745: }
746: if((bt_debug & BT_SHOWCMDS ) && ccb)
747: {
748: u_char *cp;
749: cp = ccb->scsi_cmd;
750: printf("op=%x %x %x %x %x %x\n",
751: cp[0], cp[1], cp[2],
752: cp[3], cp[4], cp[5]);
753: printf("stat %x for mbi[%d]\n"
754: , bt_mbx[unit].mbi[i].stat, i);
755: printf("addr = 0x%x\n", ccb);
756: }
757: }
758: if(ccb)
759: {
760: bt_remove_timeout(ccb);
761: bt_done(unit,ccb);
762: }
763: bt_mbx[unit].mbi[i].stat = BT_MBI_FREE;
764: }
765: }
766: return(1);
767: }
768:
769: /***********************************************\
770: * A ccb (and hence a mbx-out is put onto the *
771: * free list. *
772: \***********************************************/
773: bt_free_ccb(unit,ccb, flags)
774: struct bt_ccb *ccb;
775: {
776: unsigned int opri;
777:
778: if(scsi_debug & PRINTROUTINES)
779: printf("ccb%d(0x%x)> ",unit,flags);
780: if (!(flags & SCSI_NOMASK))
781: opri = splbio();
782:
783: ccb->next = bt_ccb_free[unit];
784: bt_ccb_free[unit] = ccb;
785: ccb->flags = CCB_FREE;
786: /***********************************************\
787: * If there were none, wake abybody waiting for *
788: * one to come free, starting with queued entries*
789: \***********************************************/
790: if (!ccb->next) {
791: wakeup(&bt_ccb_free[unit]);
792: }
793: if (!(flags & SCSI_NOMASK))
794: splx(opri);
795: }
796:
797: /***********************************************\
798: * Get a free ccb (and hence mbox-out entry) *
799: \***********************************************/
800: struct bt_ccb *
801: bt_get_ccb(unit,flags)
802: {
803: unsigned opri;
804: struct bt_ccb *rc;
805:
806: if(scsi_debug & PRINTROUTINES)
807: printf("<ccb%d(0x%x) ",unit,flags);
808: if (!(flags & SCSI_NOMASK))
809: opri = splbio();
810: /***********************************************\
811: * If we can and have to, sleep waiting for one *
812: * to come free *
813: \***********************************************/
814: while ((!(rc = bt_ccb_free[unit])) && (!(flags & SCSI_NOSLEEP)))
815: {
816: sleep(&bt_ccb_free[unit], PRIBIO);
817: }
818: if (rc)
819: {
820: bt_ccb_free[unit] = rc->next;
821: rc->flags = CCB_ACTIVE;
822: }
823: if (!(flags & SCSI_NOMASK))
824: splx(opri);
825: return(rc);
826: }
827:
828:
829: /***********************************************\
830: * We have a ccb which has been processed by the *
831: * adaptor, now we look to see how the operation *
832: * went. Wake up the owner if waiting *
833: \***********************************************/
834: bt_done(unit,ccb)
835: struct bt_ccb *ccb;
836: {
837: struct scsi_sense_data *s1,*s2;
838: struct scsi_xfer *xs = ccb->xfer;
839:
840: if(scsi_debug & (PRINTROUTINES | TRACEINTERRUPTS))
841: printf("bt_done ");
842: /***********************************************\
843: * Otherwise, put the results of the operation *
844: * into the xfer and call whoever started it *
845: \***********************************************/
846: if ( ( ccb->host_stat != BT_OK
847: || ccb->target_stat != SCSI_OK)
848: && (!(xs->flags & SCSI_ERR_OK)))
849: {
850:
851: s1 = &(ccb->scsi_sense);
852: s2 = &(xs->sense);
853:
854: if(ccb->host_stat)
855: {
856: switch(ccb->host_stat)
857: {
858: case BT_ABORTED: /* No response */
859: case BT_SEL_TIMEOUT: /* No response */
860: if (bt_debug & BT_SHOWMISC)
861: {
862: printf("timeout reported back\n");
863: }
864: xs->error = XS_TIMEOUT;
865: break;
866: default: /* Other scsi protocol messes */
867: xs->error = XS_DRIVER_STUFFUP;
868: if (bt_debug & BT_SHOWMISC)
869: {
870: printf("unexpected host_stat: %x\n",
871: ccb->host_stat);
872: }
873: }
874:
875: }
876: else
877: {
878: switch(ccb->target_stat)
879: {
880: case 0x02:
881: /* structure copy!!!!!*/
882: *s2=*s1;
883: xs->error = XS_SENSE;
884: break;
885: case 0x08:
886: xs->error = XS_BUSY;
887: break;
888: default:
889: if (bt_debug & BT_SHOWMISC)
890: {
891: printf("unexpected target_stat: %x\n",
892: ccb->target_stat);
893: }
894: xs->error = XS_DRIVER_STUFFUP;
895: }
896: }
897: }
898: else /* All went correctly OR errors expected */
899: {
900: xs->resid = 0;
901: }
902: xs->flags |= ITSDONE;
903: bt_free_ccb(unit,ccb, xs->flags);
904: if(xs->when_done)
905: (*(xs->when_done))(xs->done_arg,xs->done_arg2);
906: }
907:
908: /***********************************************\
909: * Start the board, ready for normal operation *
910: \***********************************************/
911: bt_init(unit)
912: int unit;
913: {
914: unsigned char ad[4];
915: volatile int i,sts;
916: struct bt_config conf;
917:
918: /***********************************************\
919: * reset board, If it doesn't respond, assume *
920: * that it's not there.. good for the probe *
921: \***********************************************/
922:
923: outb(BT_CTRL_STAT_PORT, BT_HRST|BT_SRST);
924:
925: for (i=0; i < BT_RESET_TIMEOUT; i++)
926: {
927: sts = inb(BT_CTRL_STAT_PORT) ;
928: if ( sts == (BT_IDLE | BT_INIT))
929: break;
930: }
931: if (i >= BT_RESET_TIMEOUT)
932: {
933: if (bt_debug & BT_SHOWMISC)
934: printf("bt_init: No answer from bt742a board\n");
935: return(ENXIO);
936: }
937:
938: /***********************************************\
939: * Assume we have a board at this stage *
940: * setup dma channel from jumpers and save int *
941: * level *
942: \***********************************************/
943: #ifdef __386BSD__
944: printf("bt%d reading board settings, ",unit);
945: #define PRNT(x)
946: #else __386BSD__
947: printf("bt%d:",unit);
948: #define PRNT(x) printf(x)
949: #endif __386BSD__
950:
951: bt_cmd(unit,0, sizeof(conf), 0 ,&conf, BT_CONF_GET);
952: switch(conf.chan)
953: {
954: case EISADMA:
955: bt_dma[unit] = -1;
956: PRNT("eisa dma ");
957: break;
958: case CHAN0:
959: outb(0x0b, 0x0c);
960: outb(0x0a, 0x00);
961: bt_dma[unit] = 0;
962: PRNT("dma=0 ");
963: break;
964: case CHAN5:
965: outb(0xd6, 0xc1);
966: outb(0xd4, 0x01);
967: bt_dma[unit] = 5;
968: PRNT("dma=5 ");
969: break;
970: case CHAN6:
971: outb(0xd6, 0xc2);
972: outb(0xd4, 0x02);
973: bt_dma[unit] = 6;
974: PRNT("dma=6 ");
975: break;
976: case CHAN7:
977: outb(0xd6, 0xc3);
978: outb(0xd4, 0x03);
979: bt_dma[unit] = 7;
980: PRNT("dma=7 ");
981: break;
982: default:
983: printf("illegal dma setting %x\n",conf.chan);
984: return(EIO);
985: }
986: switch(conf.intr)
987: {
988: case INT9:
989: bt_int[unit] = 9;
990: PRNT("int=9 ");
991: break;
992: case INT10:
993: bt_int[unit] = 10;
994: PRNT("int=10 ");
995: break;
996: case INT11:
997: bt_int[unit] = 11;
998: PRNT("int=11 ");
999: break;
1000: case INT12:
1001: bt_int[unit] = 12;
1002: PRNT("int=12 ");
1003: break;
1004: case INT14:
1005: bt_int[unit] = 14;
1006: PRNT("int=14 ");
1007: break;
1008: case INT15:
1009: bt_int[unit] = 15;
1010: PRNT("int=15 ");
1011: break;
1012: default:
1013: printf("illegal int setting\n");
1014: return(EIO);
1015: }
1016: /* who are we on the scsi bus */
1017: bt_scsi_dev[unit] = conf.scsi_dev;
1018: /***********************************************\
1019: * Initialize mail box *
1020: \***********************************************/
1021:
1022: *((physaddr *)ad) = KVTOPHYS(&bt_mbx[unit]);
1023: bt_cmd(unit,5, 0, 0, 0, BT_MBX_INIT_EXTENDED
1024: , BT_MBX_SIZE
1025: , ad[0]
1026: , ad[1]
1027: , ad[2]
1028: , ad[3]);
1029:
1030: /***********************************************\
1031: * link the ccb's with the mbox-out entries and *
1032: * into a free-list *
1033: \***********************************************/
1034: for (i=0; i < BT_MBX_SIZE; i++) {
1035: bt_ccb[unit][i].next = bt_ccb_free[unit];
1036: bt_ccb_free[unit] = &bt_ccb[unit][i];
1037: bt_ccb_free[unit]->flags = CCB_FREE;
1038: bt_ccb_free[unit]->mbx = &bt_mbx[unit].mbo[i];
1039: bt_mbx[unit].mbo[i].ccb_addr = KVTOPHYS(bt_ccb_free[unit]) ;
1040: }
1041:
1042: /***********************************************\
1043: * Note that we are going and return (to probe) *
1044: \***********************************************/
1045: bt_initialized[unit]++;
1046: return( 0 );
1047: }
1048:
1049:
1050: #ifndef min
1051: #define min(x,y) (x < y ? x : y)
1052: #endif min
1053:
1054:
1055: void btminphys(bp)
1056: struct buf *bp;
1057: {
1058: #ifdef MACH
1059: #if !defined(OSF)
1060: bp->b_flags |= B_NPAGES; /* can support scat/gather */
1061: #endif /* defined(OSF) */
1062: #endif MACH
1063: if(bp->b_bcount > ((BT_NSEG-1) * PAGESIZ))
1064: {
1065: bp->b_bcount = ((BT_NSEG-1) * PAGESIZ);
1066: }
1067: }
1068:
1069: /***********************************************\
1070: * start a scsi operation given the command and *
1071: * the data address. Also needs the unit, target *
1072: * and lu *
1073: \***********************************************/
1074: int bt_scsi_cmd(xs)
1075: struct scsi_xfer *xs;
1076: {
1077: struct scsi_sense_data *s1,*s2;
1078: struct bt_ccb *ccb;
1079: struct bt_scat_gath *sg;
1080: int seg; /* scatter gather seg being worked on */
1081: int i = 0;
1082: int rc = 0;
1083: int thiskv;
1084: physaddr thisphys,nextphys;
1085: int unit =xs->adapter;
1086: int bytes_this_seg,bytes_this_page,datalen,flags;
1087: struct iovec *iovp;
1088:
1089: if(scsi_debug & PRINTROUTINES)
1090: printf("bt_scsi_cmd ");
1091: /***********************************************\
1092: * get a ccb (mbox-out) to use. If the transfer *
1093: * is from a buf (possibly from interrupt time) *
1094: * then we can't allow it to sleep *
1095: \***********************************************/
1096: flags = xs->flags;
1097: if(xs->bp) flags |= (SCSI_NOSLEEP); /* just to be sure */
1098: if(flags & ITSDONE)
1099: {
1100: printf("Already done?");
1101: xs->flags &= ~ITSDONE;
1102: }
1103: if(!(flags & INUSE))
1104: {
1105: printf("Not in use?");
1106: xs->flags |= INUSE;
1107: }
1108: if (!(ccb = bt_get_ccb(unit,flags)))
1109: {
1110: xs->error = XS_DRIVER_STUFFUP;
1111: return(TRY_AGAIN_LATER);
1112: }
1113:
1114: if(bt_debug & BT_SHOWCCBS)
1115: printf("<start ccb(%x)>",ccb);
1116: if (ccb->mbx->cmd != BT_MBO_FREE)
1117: printf("MBO not free\n");
1118:
1119: /***********************************************\
1120: * Put all the arguments for the xfer in the ccb *
1121: \***********************************************/
1122: ccb->xfer = xs;
1123: if(flags & SCSI_RESET)
1124: {
1125: ccb->opcode = BT_RESET_CCB;
1126: }
1127: else
1128: {
1129: /* can't use S/G if zero length */
1130: ccb->opcode = (xs->datalen?
1131: BT_INIT_SCAT_GATH_CCB
1132: :BT_INITIATOR_CCB);
1133: }
1134: ccb->target = xs->targ;;
1135: ccb->data_out = 0;
1136: ccb->data_in = 0;
1137: ccb->lun = xs->lu;
1138: ccb->scsi_cmd_length = xs->cmdlen;
1139: ccb->sense_ptr = KVTOPHYS(&(ccb->scsi_sense));
1140: ccb->req_sense_length = sizeof(ccb->scsi_sense);
1141:
1142: if((xs->datalen) && (!(flags & SCSI_RESET)))
1143: { /* can use S/G only if not zero length */
1144: ccb->data_addr = KVTOPHYS(ccb->scat_gath);
1145: sg = ccb->scat_gath ;
1146: seg = 0;
1147: if(flags & SCSI_DATA_UIO)
1148: {
1149: iovp = ((struct uio *)xs->data)->uio_iov;
1150: datalen = ((struct uio *)xs->data)->uio_iovcnt;
1151: xs->datalen = 0;
1152: while ((datalen) && (seg < BT_NSEG))
1153: {
1154: sg->seg_addr = (physaddr)iovp->iov_base;
1155: xs->datalen += sg->seg_len = iovp->iov_len;
1156: if(scsi_debug & SHOWSCATGATH)
1157: printf("(0x%x@0x%x)"
1158: ,iovp->iov_len
1159: ,iovp->iov_base);
1160: sg++;
1161: iovp++;
1162: seg++;
1163: datalen--;
1164: }
1165: }
1166: else
1167: {
1168: /***********************************************\
1169: * Set up the scatter gather block *
1170: \***********************************************/
1171:
1172: if(scsi_debug & SHOWSCATGATH)
1173: printf("%d @0x%x:- ",xs->datalen,xs->data);
1174: datalen = xs->datalen;
1175: thiskv = (int)xs->data;
1176: thisphys = KVTOPHYS(thiskv);
1177:
1178: while ((datalen) && (seg < BT_NSEG))
1179: {
1180: bytes_this_seg = 0;
1181:
1182: /* put in the base address */
1183: sg->seg_addr = thisphys;
1184:
1185: if(scsi_debug & SHOWSCATGATH)
1186: printf("0x%x",thisphys);
1187:
1188: /* do it at least once */
1189: nextphys = thisphys;
1190: while ((datalen) && (thisphys == nextphys))
1191: /*********************************************\
1192: * This page is contiguous (physically) with *
1193: * the the last, just extend the length *
1194: \*********************************************/
1195: {
1196: /* how far to the end of the page */
1197: nextphys= (thisphys & (~(PAGESIZ - 1)))
1198: + PAGESIZ;
1199: bytes_this_page = nextphys - thisphys;
1200: /**** or the data ****/
1201: bytes_this_page = min(bytes_this_page
1202: ,datalen);
1203: bytes_this_seg += bytes_this_page;
1204: datalen -= bytes_this_page;
1205:
1206: /* get more ready for the next page */
1207: thiskv = (thiskv & (~(PAGESIZ - 1)))
1208: + PAGESIZ;
1209: if(datalen)
1210: thisphys = KVTOPHYS(thiskv);
1211: }
1212: /********************************************\
1213: * next page isn't contiguous, finish the seg *
1214: \********************************************/
1215: if(scsi_debug & SHOWSCATGATH)
1216: printf("(0x%x)",bytes_this_seg);
1217: sg->seg_len = bytes_this_seg;
1218: sg++;
1219: seg++;
1220: }
1221: } /*end of iov/kv decision */
1222: ccb->data_length = seg * sizeof(struct bt_scat_gath);
1223: if(scsi_debug & SHOWSCATGATH)
1224: printf("\n");
1225: if (datalen)
1226: { /* there's still data, must have run out of segs! */
1227: printf("bt_scsi_cmd%d: more than %d DMA segs\n",
1228: unit,BT_NSEG);
1229: xs->error = XS_DRIVER_STUFFUP;
1230: bt_free_ccb(unit,ccb,flags);
1231: return(HAD_ERROR);
1232: }
1233:
1234: }
1235: else
1236: { /* No data xfer, use non S/G values */
1237: ccb->data_addr = (physaddr)0;
1238: ccb->data_length = 0;
1239: }
1240: ccb->link_id = 0;
1241: ccb->link_addr = (physaddr)0;
1242: /***********************************************\
1243: * Put the scsi command in the ccb and start it *
1244: \***********************************************/
1245: if(!(flags & SCSI_RESET))
1246: {
1247: bcopy(xs->cmd, ccb->scsi_cmd, ccb->scsi_cmd_length);
1248: }
1249: if(scsi_debug & SHOWCOMMANDS)
1250: {
1251: u_char *b = ccb->scsi_cmd;
1252: if(!(flags & SCSI_RESET))
1253: {
1254: int i = 0;
1255: printf("bt%d:%d:%d-"
1256: ,unit
1257: ,ccb->target
1258: ,ccb->lun);
1259: while(i < ccb->scsi_cmd_length )
1260: {
1261: if(i) printf(",");
1262: printf("%x",b[i++]);
1263: }
1264: printf("-\n");
1265: }
1266: else
1267: {
1268: printf("bt%d:%d:%d-RESET- "
1269: ,unit
1270: ,ccb->target
1271: ,ccb->lun
1272: );
1273: }
1274: }
1275: bt_startmbx(ccb->mbx);
1276: /***********************************************\
1277: * Usually return SUCCESSFULLY QUEUED *
1278: \***********************************************/
1279: if(scsi_debug & TRACEINTERRUPTS)
1280: printf("cmd_sent ");
1281: if (!(flags & SCSI_NOMASK))
1282: {
1283: bt_add_timeout(ccb,xs->timeout);
1284: return(SUCCESSFULLY_QUEUED);
1285: }
1286: /***********************************************\
1287: * If we can't use interrupts, poll on completion*
1288: \***********************************************/
1289: {
1290: int done = 0;
1291: int count = delaycount * xs->timeout / BT_SCSI_TIMEOUT_FUDGE;
1292: if(scsi_debug & TRACEINTERRUPTS)
1293: printf("wait ");
1294: while((!done) && count)
1295: {
1296: i=0;
1297: while ( (!done) && i<BT_MBX_SIZE)
1298: {
1299: if ((bt_mbx[unit].mbi[i].stat != BT_MBI_FREE )
1300: && (PHYSTOKV(bt_mbx[unit].mbi[i].ccb_addr)
1301: == (int)ccb))
1302: {
1303: bt_mbx[unit].mbi[i].stat = BT_MBI_FREE;
1304: bt_done(unit,ccb);
1305: done++;
1306: }
1307: i++;
1308: }
1309: count--;
1310: }
1311: if (!count)
1312: {
1313: if (!(xs->flags & SCSI_SILENT))
1314: printf("cmd fail\n");
1315: bt_abortmbx(ccb->mbx);
1316: count = delaycount * 2000 / BT_SCSI_TIMEOUT_FUDGE;
1317: while((!done) && count)
1318: {
1319: i=0;
1320: while ( (!done) && i<BT_MBX_SIZE)
1321: {
1322: if ((bt_mbx[unit].mbi[i].stat != BT_MBI_FREE )
1323: && (PHYSTOKV((bt_mbx[unit].mbi[i].ccb_addr)
1324: == (int)ccb)))
1325: {
1326: bt_mbx[unit].mbi[i].stat = BT_MBI_FREE;
1327: bt_done(unit,ccb);
1328: done++;
1329: }
1330: i++;
1331: }
1332: count--;
1333: }
1334: if(!count)
1335: {
1336: printf("abort failed in wait\n");
1337: ccb->mbx->cmd = BT_MBO_FREE;
1338: }
1339: bt_free_ccb(unit,ccb,flags);
1340: btintr(unit);
1341: xs->error = XS_DRIVER_STUFFUP;
1342: return(HAD_ERROR);
1343: }
1344: btintr(unit);
1345: if(xs->error) return(HAD_ERROR);
1346: return(COMPLETE);
1347: }
1348: }
1349:
1350: /*
1351: * +----------+ +----------+ +----------+
1352: * bt_soonest--->| later |---->| later|---->| later|--->0
1353: * | [Delta] | | [Delta] | | [Delta] |
1354: * 0<-----|sooner |<----|sooner |<----|sooner |<----bt_latest
1355: * +----------+ +----------+ +----------+
1356: *
1357: * bt_furtherest = sum(Delta[1..n])
1358: */
1359: bt_add_timeout(ccb,time)
1360: struct bt_ccb *ccb;
1361: int time;
1362: {
1363: int timeprev;
1364: struct bt_ccb *prev;
1365: int s = splbio();
1366:
1367: if(prev = bt_latest) /* yes, an assign */
1368: {
1369: timeprev = bt_furtherest;
1370: }
1371: else
1372: {
1373: timeprev = 0;
1374: }
1375: while(prev && (timeprev > time))
1376: {
1377: timeprev -= prev->delta;
1378: prev = prev->sooner;
1379: }
1380: if(prev)
1381: {
1382: ccb->delta = time - timeprev;
1383: if( ccb->later = prev->later) /* yes an assign */
1384: {
1385: ccb->later->sooner = ccb;
1386: ccb->later->delta -= ccb->delta;
1387: }
1388: else
1389: {
1390: bt_furtherest = time;
1391: bt_latest = ccb;
1392: }
1393: ccb->sooner = prev;
1394: prev->later = ccb;
1395: }
1396: else
1397: {
1398: if( ccb->later = bt_soonest) /* yes, an assign*/
1399: {
1400: ccb->later->sooner = ccb;
1401: ccb->later->delta -= time;
1402: }
1403: else
1404: {
1405: bt_furtherest = time;
1406: bt_latest = ccb;
1407: }
1408: ccb->delta = time;
1409: ccb->sooner = (struct bt_ccb *)0;
1410: bt_soonest = ccb;
1411: }
1412: splx(s);
1413: }
1414:
1415: bt_remove_timeout(ccb)
1416: struct bt_ccb *ccb;
1417: {
1418: int s = splbio();
1419:
1420: if(ccb->sooner)
1421: {
1422: ccb->sooner->later = ccb->later;
1423: }
1424: else
1425: {
1426: bt_soonest = ccb->later;
1427: }
1428: if(ccb->later)
1429: {
1430: ccb->later->sooner = ccb->sooner;
1431: ccb->later->delta += ccb->delta;
1432: }
1433: else
1434: {
1435: bt_latest = ccb->sooner;
1436: bt_furtherest -= ccb->delta;
1437: }
1438: ccb->sooner = ccb->later = (struct bt_ccb *)0;
1439: splx(s);
1440: }
1441:
1442:
1443: extern int hz;
1444: #define ONETICK 500 /* milliseconds */
1445: #define SLEEPTIME ((hz * 1000) / ONETICK)
1446: bt_timeout(arg)
1447: int arg;
1448: {
1449: struct bt_ccb *ccb;
1450: int unit;
1451: int s = splbio();
1452:
1453: while( ccb = bt_soonest )
1454: {
1455: if(ccb->delta <= ONETICK)
1456: /***********************************************\
1457: * It has timed out, we need to do some work *
1458: \***********************************************/
1459: {
1460: unit = ccb->xfer->adapter;
1461: printf("bt%d:%d device timed out\n",unit
1462: ,ccb->xfer->targ);
1463: if(bt_debug & BT_SHOWCCBS)
1464: tfs_print_active_ccbs();
1465:
1466: /***************************************\
1467: * Unlink it from the queue *
1468: \***************************************/
1469: bt_remove_timeout(ccb);
1470:
1471: /***************************************\
1472: * If The ccb's mbx is not free, then *
1473: * the board has gone south *
1474: \***************************************/
1475: if(ccb->mbx->cmd != BT_MBO_FREE)
1476: {
1477: printf("bt%d not taking commands!\n"
1478: ,unit);
1479: Debugger();
1480: }
1481: /***************************************\
1482: * If it has been through before, then *
1483: * a previous abort has failed, don't *
1484: * try abort again *
1485: \***************************************/
1486: if(ccb->flags == CCB_ABORTED) /* abort timed out */
1487: {
1488: printf("AGAIN");
1489: ccb->xfer->retries = 0; /* I MEAN IT ! */
1490: ccb->host_stat = BT_ABORTED;
1491: bt_done(unit,ccb);
1492: }
1493: else /* abort the operation that has timed out */
1494: {
1495: printf("\n");
1496: bt_abortmbx(ccb->mbx);
1497: /* 2 secs for the abort */
1498: bt_add_timeout(ccb,2000 + ONETICK);
1499: ccb->flags = CCB_ABORTED;
1500: }
1501: }
1502: else
1503: /***********************************************\
1504: * It has not timed out, adjust and leave *
1505: \***********************************************/
1506: {
1507: ccb->delta -= ONETICK;
1508: bt_furtherest -= ONETICK;
1509: break;
1510: }
1511: }
1512: splx(s);
1513: timeout(bt_timeout,arg,SLEEPTIME);
1514: }
1515:
1516: tfs_print_ccb(ccb)
1517: struct bt_ccb *ccb;
1518: {
1519: printf("ccb:%x op:%x cmdlen:%d senlen:%d\n"
1520: ,ccb
1521: ,ccb->opcode
1522: ,ccb->scsi_cmd_length
1523: ,ccb->req_sense_length);
1524: printf(" datlen:%d hstat:%x tstat:%x delta:%d flags:%x\n"
1525: ,ccb->data_length
1526: ,ccb->host_stat
1527: ,ccb->target_stat
1528: ,ccb->delta
1529: ,ccb->flags);
1530: }
1531:
1532: tfs_print_active_ccbs()
1533: {
1534: struct bt_ccb *ccb;
1535: ccb = bt_soonest;
1536:
1537: while(ccb)
1538: {
1539: tfs_print_ccb(ccb);
1540: ccb = ccb->later;
1541: }
1542: printf("Furtherest = %d\n",bt_furtherest);
1543: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.