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