diff --git a/sys/i386/eisa/aha1742.c b/sys/i386/eisa/aha1742.c index 774e6f88e40..b4e4d98fac1 100644 --- a/sys/i386/eisa/aha1742.c +++ b/sys/i386/eisa/aha1742.c @@ -11,41 +11,15 @@ * TFS supplies this software to be publicly redistributed * on the understanding that TFS is not responsible for the correct * functioning of this software in any circumstances. - */ - -/* - * HISTORY - * $Log: aha1742.c,v $ - * Revision 1.4 1993/08/06 11:59:02 rgrimes - * Fixed **probing for scsi devices** message to have a controller and unit - * message on the begining of it: - * aha0: **probing for scsi devices** * - * Revision 1.3 1993/07/29 11:55:34 nate - * Syncing our sources back with Julian's, and removing PATCHKIT headers. * - * Large Bustek changes, most everything else is minimal. + * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE + * -------------------- ----- ---------------------- + * CURRENT PATCH LEVEL: 1 00098 + * -------------------- ----- ---------------------- * - * Revision 1.2 1993/07/15 17:52:58 davidg - * Modified attach printf's so that the output is compatible with the "new" - * way of doing things. There still remain several drivers that need to - * be updated. Also added a compile-time option to pccons to switch the - * control and caps-lock keys (REVERSE_CAPS_CTRL) - added for my personal - * sanity. - * - * Revision 1.1.1.1 1993/06/12 14:57:59 rgrimes - * Initial import, 0.1 + pk 0.2.4-B1 - * - * julian - removed un-necessary splx() calls and debugging code - * - * Revision 1.3 93/05/22 16:51:18 julian - * set up dev->dev_pic before it's needed for OSF - * - * Revision 1.2 93/05/07 11:40:27 julian - * fixed SLEEPTIME calculation - * - * Revision 1.1 93/05/07 11:14:03 julian - * Initial revision + * 16 Feb 93 Julian Elischer ADDED for SCSI system + * commenced: Sun Sep 27 18:14:01 PDT 1992 */ #include @@ -103,6 +77,7 @@ int Debugger(); #endif MACH typedef unsigned long int physaddr; +extern int hz; #ifdef MACH extern physaddr kvtophys(); @@ -297,8 +272,6 @@ struct ecb /*-----------------end of hardware supported fields----------------*/ struct ecb *next; /* in free list */ struct scsi_xfer *xs; /* the scsi_xfer for this cmd */ - long int delta; /* difference from previous*/ - struct ecb *later,*sooner; int flags; #define ECB_FREE 0 #define ECB_ACTIVE 1 @@ -310,9 +283,6 @@ struct ecb struct scsi_sense_data ecb_sense; }; -struct ecb *ahb_soonest = (struct ecb *)0; -struct ecb *ahb_latest = (struct ecb *)0; -long int ahb_furtherest = 0; /* longest time in the timeout queue */ /* */ struct ahb_data @@ -546,6 +516,7 @@ struct isa_dev *dev; #ifdef __386BSD__ /* 386BSD */ dev->id_irq = (1 << ahb_data[unit].vect); dev->id_drq = -1; /* use EISA dma */ + printf("\n **"); #endif __386BSD__ ahb_unit++; @@ -562,7 +533,7 @@ struct isa_dev *dev; #ifdef __386BSD__ - printf("ahb%d: **probing for scsi devices**\n", unit); + printf(" probing for scsi devices**\n"); #endif __386BSD__ /***********************************************\ @@ -572,10 +543,9 @@ struct isa_dev *dev; #if defined(OSF) ahb_attached[unit]=1; #endif /* defined(OSF) */ - if(!unit) /* only one for all boards */ - { - ahb_timeout(0); - } +#ifdef __386BSD__ + printf("ahb%d",unit); +#endif __386BSD__ return; } @@ -603,8 +573,10 @@ ahbintr(unit) int port = ahb_data[unit].baseport; +#ifdef AHBDEBUG if(scsi_debug & PRINTROUTINES) printf("ahbintr "); +#endif /*AHBDEBUG*/ #if defined(OSF) if (!ahb_attached[unit]) @@ -623,8 +595,10 @@ ahbintr(unit) stat = ahbstat & G2INTST_INT_STAT; mboxval = inl(port + MBOXIN0);/* don't know this will work */ outb(port + G2CNTRL, G2CNTRL_CLEAR_EISA_INT); +#ifdef AHBDEBUG if(scsi_debug & TRACEINTERRUPTS) printf("status = 0x%x ",stat); +#endif /*AHBDEBUG*/ /***********************************************\ * Process the completed operation * \***********************************************/ @@ -647,13 +621,9 @@ ahbintr(unit) ahb_data[unit].immed_ecb = 0; break; case AHB_ASN: /* for target mode */ - printf("ahb%d: Unexpected ASN interrupt(%x)\n", - unit, mboxval); ecb = 0; break; case AHB_HW_ERR: - printf("ahb%d: Hardware error interrupt(%x)\n", - unit, mboxval); ecb = 0; break; case AHB_ECB_RECOVERED: @@ -669,13 +639,15 @@ ahbintr(unit) } if(ecb) { +#ifdef AHBDEBUG if(ahb_debug & AHB_SHOWCMDS ) { ahb_show_scsi_cmd(ecb->xs); } if((ahb_debug & AHB_SHOWECBS) && ecb) printf("",ecb); - ahb_remove_timeout(ecb); +#endif /*AHBDEBUG*/ + untimeout(ahb_timeout,ecb); ahb_done(unit,ecb,((stat == AHB_ECB_OK)?SUCCESS:FAIL)); } } @@ -695,8 +667,10 @@ struct ecb *ecb; struct scsi_sense_data *s1,*s2; struct scsi_xfer *xs = ecb->xs; +#ifdef AHBDEBUG if(scsi_debug & (PRINTROUTINES | TRACEINTERRUPTS)) printf("ahb_done "); +#endif /*AHBDEBUG*/ /***********************************************\ * Otherwise, put the results of the operation * * into the xfer and call whoever started it * @@ -732,19 +706,23 @@ struct ecb *ecb; case HS_CMD_ABORTED_ADAPTER: /* No response */ break; case HS_TIMED_OUT: /* No response */ +#ifdef AHBDEBUG if (ahb_debug & AHB_SHOWMISC) { printf("timeout reported back\n"); } +#endif /*AHBDEBUG*/ xs->error = XS_TIMEOUT; break; default: /* Other scsi protocol messes */ xs->error = XS_DRIVER_STUFFUP; +#ifdef AHBDEBUG if (ahb_debug & AHB_SHOWMISC) { printf("unexpected ha_status: %x\n", stat->ha_status); } +#endif /*AHBDEBUG*/ } } @@ -761,11 +739,13 @@ struct ecb *ecb; xs->error = XS_BUSY; break; default: +#ifdef AHBDEBUG if (ahb_debug & AHB_SHOWMISC) { printf("unexpected targ_status: %x\n", stat->targ_status); } +#endif /*AHBDEBUG*/ xs->error = XS_DRIVER_STUFFUP; } } @@ -785,8 +765,10 @@ struct ecb *ecb; { unsigned int opri; +#ifdef AHBDEBUG if(scsi_debug & PRINTROUTINES) printf("ecb%d(0x%x)> ",unit,flags); +#endif /*AHBDEBUG*/ if (!(flags & SCSI_NOMASK)) opri = splbio(); @@ -813,8 +795,10 @@ ahb_get_ecb(unit,flags) unsigned opri; struct ecb *rc; +#ifdef AHBDEBUG if(scsi_debug & PRINTROUTINES) printf("",ecb); if(scsi_debug & SHOWCOMMANDS) { ahb_show_scsi_cmd(xs); } +#endif /*AHBDEBUG*/ ecb->xs = xs; /***********************************************\ * If it's a reset, we need to do an 'immediate' * @@ -1039,7 +1030,7 @@ cheat = ecb; { s = splbio(); ahb_send_immed(unit,xs->targ,AHB_TARG_RESET); - ahb_add_timeout(ecb,xs->timeout); + timeout(ahb_timeout,ecb,(xs->timeout * hz)/1000); splx(s); return(SUCCESSFULLY_QUEUED); } @@ -1049,8 +1040,10 @@ cheat = ecb; /***********************************************\ * If we can't use interrupts, poll on completion* \***********************************************/ +#ifdef AHBDEBUG if(scsi_debug & TRACEINTERRUPTS) printf("wait "); +#endif /*AHBDEBUG*/ if( ahb_poll(unit,xs->timeout)) { ahb_free_ecb(unit,ecb,flags); @@ -1089,10 +1082,12 @@ cheat = ecb; { sg->addr = (physaddr)iovp->iov_base; xs->datalen += sg->len = iovp->iov_len; +#ifdef AHBDEBUG if(scsi_debug & SHOWSCATGATH) printf("(0x%x@0x%x)" ,iovp->iov_len ,iovp->iov_base); +#endif /*AHBDEBUG*/ sg++; iovp++; seg++; @@ -1105,8 +1100,10 @@ cheat = ecb; * Set up the scatter gather block * \***********************************************/ +#ifdef AHBDEBUG if(scsi_debug & SHOWSCATGATH) printf("%d @0x%x:- ",xs->datalen,xs->data); +#endif /*AHBDEBUG*/ datalen = xs->datalen; thiskv = (int)xs->data; thisphys = KVTOPHYS(thiskv); @@ -1118,8 +1115,10 @@ cheat = ecb; /* put in the base address */ sg->addr = thisphys; +#ifdef AHBDEBUG if(scsi_debug & SHOWSCATGATH) printf("0x%x",thisphys); +#endif /*AHBDEBUG*/ /* do it at least once */ nextphys = thisphys; @@ -1148,16 +1147,20 @@ cheat = ecb; /********************************************\ * next page isn't contiguous, finish the seg * \********************************************/ +#ifdef AHBDEBUG if(scsi_debug & SHOWSCATGATH) printf("(0x%x)",bytes_this_seg); +#endif /*AHBDEBUG*/ sg->len = bytes_this_seg; sg++; seg++; } } /*end of iov/kv decision */ ecb->datalen = seg * sizeof(struct ahb_dma_seg); +#ifdef AHBDEBUG if(scsi_debug & SHOWSCATGATH) printf("\n"); +#endif /*AHBDEBUG*/ if (datalen) { /* there's still data, must have run out of segs! */ printf("ahb_scsi_cmd%d: more than %d DMA segs\n", @@ -1185,18 +1188,22 @@ cheat = ecb; { s = splbio(); ahb_send_mbox(unit,OP_START_ECB,xs->targ,ecb); - ahb_add_timeout(ecb,xs->timeout); + timeout(ahb_timeout,ecb,(xs->timeout * hz)/1000); splx(s); +#ifdef AHBDEBUG if(scsi_debug & TRACEINTERRUPTS) printf("cmd_sent "); +#endif /*AHBDEBUG*/ return(SUCCESSFULLY_QUEUED); } /***********************************************\ * If we can't use interrupts, poll on completion* \***********************************************/ ahb_send_mbox(unit,OP_START_ECB,xs->targ,ecb); +#ifdef AHBDEBUG if(scsi_debug & TRACEINTERRUPTS) printf("cmd_wait "); +#endif /*AHBDEBUG*/ do { if(ahb_poll(unit,xs->timeout)) @@ -1219,172 +1226,55 @@ cheat = ecb; return(COMPLETE); } -/* - * +----------+ +----------+ +----------+ - * ahb_soonest--->| later |--->| later|--->| later|--->0 - * | [Delta] | | [Delta] | | [Delta] | - * 0<---|sooner |<---|sooner |<---|sooner |<---ahb_latest - * +----------+ +----------+ +----------+ - * - * ahb_furtherest = sum(Delta[1..n]) - */ -ahb_add_timeout(ecb,time) -struct ecb *ecb; -int time; + +ahb_timeout(struct ecb *ecb) { - int timeprev; - struct ecb *prev; - int s = splbio(); - - if(prev = ahb_latest) /* yes, an assign */ - { - timeprev = ahb_furtherest; - } - else - { - timeprev = 0; - } - while(prev && (timeprev > time)) - { - timeprev -= prev->delta; - prev = prev->sooner; - } - if(prev) - { - ecb->delta = time - timeprev; - if( ecb->later = prev->later) /* yes an assign */ - { - ecb->later->sooner = ecb; - ecb->later->delta -= ecb->delta; - } - else - { - ahb_furtherest = time; - ahb_latest = ecb; - } - ecb->sooner = prev; - prev->later = ecb; - } - else - { - if( ecb->later = ahb_soonest) /* yes, an assign*/ - { - ecb->later->sooner = ecb; - ecb->later->delta -= time; - } - else - { - ahb_furtherest = time; - ahb_latest = ecb; - } - ecb->delta = time; - ecb->sooner = (struct ecb *)0; - ahb_soonest = ecb; - } - splx(s); -} - -ahb_remove_timeout(ecb) -struct ecb *ecb; -{ - int s = splbio(); - - if(ecb->sooner) - { - ecb->sooner->later = ecb->later; - } - else - { - ahb_soonest = ecb->later; - } - if(ecb->later) - { - ecb->later->sooner = ecb->sooner; - ecb->later->delta += ecb->delta; - } - else - { - ahb_latest = ecb->sooner; - ahb_furtherest -= ecb->delta; - } - ecb->sooner = ecb->later = (struct ecb *)0; - splx(s); -} - - -extern int hz; -#define ONETICK 500 /* milliseconds */ -#define SLEEPTIME ((hz * ONETICK) / 1000) -ahb_timeout(arg) -int arg; -{ - struct ecb *ecb; int unit; int s = splbio(); - while( ecb = ahb_soonest ) + unit = ecb->xs->adapter; + printf("ahb%d:%d device timed out\n",unit + ,ecb->xs->targ); +#ifdef AHBDEBUG + if(ahb_debug & AHB_SHOWECBS) + ahb_print_active_ecb(unit); +#endif /*AHBDEBUG*/ + + /***************************************\ + * If it's immediate, don't try abort it * + \***************************************/ + if(ecb->flags & ECB_IMMED) { - if(ecb->delta <= ONETICK) - /***********************************************\ - * It has timed out, we need to do some work * - \***********************************************/ - { - unit = ecb->xs->adapter; - printf("ahb%d:%d device timed out\n",unit - ,ecb->xs->targ); - if(ahb_debug & AHB_SHOWECBS) - ahb_print_active_ecb(); - - /***************************************\ - * Unlink it from the queue * - \***************************************/ - ahb_remove_timeout(ecb); - - /***************************************\ - * If it's immediate, don't try abort it * - \***************************************/ - if(ecb->flags & ECB_IMMED) - { - ecb->xs->retries = 0; /* I MEAN IT ! */ - ecb->flags |= ECB_IMMED_FAIL; - ahb_done(unit,ecb,FAIL); - continue; - } - /***************************************\ - * If it has been through before, then * - * a previous abort has failed, don't * - * try abort again * - \***************************************/ - if(ecb->flags == ECB_ABORTED) /* abort timed out */ - { - printf("AGAIN"); - ecb->xs->retries = 0; /* I MEAN IT ! */ - ecb->ecb_status.ha_status = HS_CMD_ABORTED_HOST; - ahb_done(unit,ecb,FAIL); - } - else /* abort the operation that has timed out */ - { - printf("\n"); - ahb_send_mbox(unit,OP_ABORT_ECB,ecb->xs->targ,ecb); - /* 2 secs for the abort */ - ahb_add_timeout(ecb,2000 + ONETICK); - ecb->flags = ECB_ABORTED; - } - } - else - /***********************************************\ - * It has not timed out, adjust and leave * - \***********************************************/ - { - ecb->delta -= ONETICK; - ahb_furtherest -= ONETICK; - break; - } + ecb->xs->retries = 0; /* I MEAN IT ! */ + ecb->flags |= ECB_IMMED_FAIL; + ahb_done(unit,ecb,FAIL); + splx(s); + return; + } + /***************************************\ + * If it has been through before, then * + * a previous abort has failed, don't * + * try abort again * + \***************************************/ + if(ecb->flags == ECB_ABORTED) /* abort timed out */ + { + printf("AGAIN"); + ecb->xs->retries = 0; /* I MEAN IT ! */ + ecb->ecb_status.ha_status = HS_CMD_ABORTED_HOST; + ahb_done(unit,ecb,FAIL); + } + else /* abort the operation that has timed out */ + { + printf("\n"); + ahb_send_mbox(unit,OP_ABORT_ECB,ecb->xs->targ,ecb); + /* 2 secs for the abort */ + timeout(ahb_timeout,ecb,2 * hz); + ecb->flags = ECB_ABORTED; } splx(s); - timeout(ahb_timeout,arg,SLEEPTIME); } +#ifdef AHBDEBUG ahb_show_scsi_cmd(struct scsi_xfer *xs) { u_char *b = (u_char *)xs->cmd; @@ -1419,24 +1309,26 @@ struct ecb *ecb; ,ecb->opcode ,ecb->cdblen ,ecb->senselen); - printf(" datlen:%d hstat:%x tstat:%x delta:%d flags:%x\n" + printf(" datlen:%d hstat:%x tstat:%x flags:%x\n" ,ecb->datalen ,ecb->ecb_status.ha_status ,ecb->ecb_status.targ_status - ,ecb->delta ,ecb->flags); ahb_show_scsi_cmd(ecb->xs); } -ahb_print_active_ecb() +ahb_print_active_ecb(int unit) { - struct ecb *ecb; - ecb = ahb_soonest; + struct ecb *ecb = ahb_data[unit].ecbs; + int i = NUM_CONCURRENT; - while(ecb) + while(i--) { - ahb_print_ecb(ecb); - ecb = ecb->later; + if(ecb->flags != ECB_FREE) + { + ahb_print_ecb(ecb); + } + ecb++; } - printf("Furtherest = %d\n",ahb_furtherest); } +#endif /*AHBDEBUG */ diff --git a/sys/i386/isa/aha1542.c b/sys/i386/isa/aha1542.c index a0ec147bd8c..b5107393e94 100644 --- a/sys/i386/isa/aha1542.c +++ b/sys/i386/isa/aha1542.c @@ -12,6 +12,13 @@ * on the understanding that TFS is not responsible for the correct * functioning of this software in any circumstances. * + * + * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE + * -------------------- ----- ---------------------- + * CURRENT PATCH LEVEL: 1 00098 + * -------------------- ----- ---------------------- + * + * 16 Feb 93 Julian Elischer ADDED for SCSI system */ /* @@ -20,34 +27,17 @@ /* * HISTORY - * $Log: aha1542.c,v $ - * Revision 1.4 1993/08/06 11:58:59 rgrimes - * Fixed **probing for scsi devices** message to have a controller and unit - * message on the begining of it: - * aha0: **probing for scsi devices** - * - * Revision 1.3 1993/07/29 11:55:31 nate - * Syncing our sources back with Julian's, and removing PATCHKIT headers. - * - * Large Bustek changes, most everything else is minimal. - * - * Revision 1.2 1993/07/15 17:52:58 davidg - * Modified attach printf's so that the output is compatible with the "new" - * way of doing things. There still remain several drivers that need to - * be updated. Also added a compile-time option to pccons to switch the - * control and caps-lock keys (REVERSE_CAPS_CTRL) - added for my personal - * sanity. - * - * Revision 1.1.1.1 1993/06/12 14:57:59 rgrimes - * Initial import, 0.1 + pk 0.2.4-B1 - * - * Revision 1.3 93/05/22 16:51:18 julian + * $Log: aha1542.c,v $ + * Revision 1.4 93/08/07 13:17:25 julian + * replaced private timeout stuff with system timeout calls + * + * Revision 1.3 93/05/22 16:51:18 root * set up dev->dev_pic before it's needed for OSF * - * Revision 1.2 93/05/07 11:40:27 julian + * Revision 1.2 93/05/07 11:40:27 root * fixed SLEEPTIME calculation * - * Revision 1.1 93/05/07 11:14:03 julian + * Revision 1.1 93/05/07 11:14:03 root * Initial revision * * Revision 1.6 1992/08/24 21:01:58 jason @@ -148,6 +138,7 @@ int Debugger(); #define Debugger() panic("should call debugger here (adaptec.c)") #endif NDDB #endif __386BSD__ +extern int hz; extern int delaycount; /* from clock setup code */ /************************** board definitions *******************************/ @@ -280,8 +271,6 @@ struct aha_ccb { struct aha_ccb *next; struct scsi_xfer *xfer; /* the scsi_xfer for this cmd */ struct aha_mbx_out *mbx; /* pointer to mail box */ - long int delta; /* difference from previous*/ - struct aha_ccb *later,*sooner; int flags; #define CCB_FREE 0 #define CCB_ACTIVE 1 @@ -289,9 +278,6 @@ struct aha_ccb { }; -struct aha_ccb *aha_soonest = (struct aha_ccb *)0; -struct aha_ccb *aha_latest = (struct aha_ccb *)0; -long int aha_furtherest = 0; /* longest time in the timeout queue */ /* * opcode fields @@ -403,7 +389,9 @@ int aha_initialized[NAHA]; #ifdef OSF int aha_attached[NAHA]; #endif OSF -int aha_debug = 0; +#ifdef AHADEBUG +int aha_debug = 1; +#endif /*AHADEBUG*/ int ahaprobe(), ahaattach(), ahaintr(); #ifdef MACH @@ -643,6 +631,7 @@ struct isa_dev *dev; panic("Unable to add aha interrupt handler"); #endif /* !defined(OSF) */ #ifdef __386BSD__ + printf("\n **"); #else __386BSD__ printf("port=%x spl=%d\n", dev->dev_addr, dev->dev_spl); @@ -660,7 +649,7 @@ struct isa_dev *dev; int unit = dev->dev_unit; #ifdef __386BSD__ - printf("aha%d: **probing for scsi devices**\n", unit); + printf(" probing for scsi devices**\n"); #endif __386BSD__ /***********************************************\ * ask the adapter what subunits are present * @@ -669,10 +658,9 @@ struct isa_dev *dev; #if defined(OSF) aha_attached[unit]=1; #endif /* defined(OSF) */ - if(!unit) /* only one for all boards */ - { - aha_timeout(0); - } +#ifdef __386BSD__ + printf("aha%d",unit); +#endif __386BSD__ return; } @@ -697,8 +685,10 @@ ahaintr(unit) unsigned char stat; register i; +#ifdef AHADEBUG if(scsi_debug & PRINTROUTINES) printf("ahaintr "); +#endif /*AHADEBUG*/ /***********************************************\ * First acknowlege the interrupt, Then if it's * * not telling about a completed operation * @@ -706,12 +696,16 @@ ahaintr(unit) \***********************************************/ stat = inb(AHA_INTR_PORT); outb(AHA_CTRL_STAT_PORT, AHA_IRST); +#ifdef AHADEBUG if(scsi_debug & TRACEINTERRUPTS) printf("int "); +#endif /*AHADEBUG*/ if (! (stat & AHA_MBIF)) return(1); +#ifdef AHADEBUG if(scsi_debug & TRACEINTERRUPTS) printf("b "); +#endif /*AHADEBUG*/ #if defined(OSF) if (!aha_attached[unit]) { @@ -733,15 +727,19 @@ ahaintr(unit) switch(stat) { case AHA_MBI_ABORT: +#ifdef AHADEBUG if(aha_debug) printf("abort"); +#endif /*AHADEBUG*/ ccb->host_stat = AHA_ABORTED; break; case AHA_MBI_UNKNOWN: ccb = (struct aha_ccb *)0; +#ifdef AHADEBUG if(aha_debug) printf("unknown ccb for abort "); +#endif /*AHADEBUG*/ /* may have missed it */ /* no such ccb known for abort */ @@ -752,6 +750,7 @@ ahaintr(unit) panic("Impossible mbxi status"); } +#ifdef AHADEBUG if( aha_debug && ccb ) { u_char *cp; @@ -763,10 +762,11 @@ ahaintr(unit) , aha_mbx[unit].mbi[i].stat, i); printf("addr = 0x%x\n", ccb); } +#endif /*AHADEBUG*/ } if(ccb) { - aha_remove_timeout(ccb); + untimeout(aha_timeout,ccb); aha_done(unit,ccb); } aha_mbx[unit].mbi[i].stat = AHA_MBI_FREE; @@ -784,19 +784,16 @@ struct aha_ccb *ccb; { unsigned int opri; +#ifdef AHADEBUG if(scsi_debug & PRINTROUTINES) printf("ccb%d(0x%x)> ",unit,flags); +#endif /*AHADEBUG*/ if (!(flags & SCSI_NOMASK)) opri = splbio(); ccb->next = aha_ccb_free[unit]; aha_ccb_free[unit] = ccb; ccb->flags = CCB_FREE; - if(ccb->sooner || ccb->later) - { - printf("yikes, still in timeout queue\n"); - aha_remove_timeout(ccb); - } /***********************************************\ * If there were none, wake abybody waiting for * * one to come free, starting with queued entries* @@ -817,8 +814,10 @@ aha_get_ccb(unit,flags) unsigned opri; struct aha_ccb *rc; +#ifdef AHADEBUG if(scsi_debug & PRINTROUTINES) printf("xfer; +#ifdef AHADEBUG if(scsi_debug & PRINTROUTINES ) printf("aha_done "); +#endif /*AHADEBUG*/ /***********************************************\ * Otherwise, put the results of the operation * * into the xfer and call whoever started it * @@ -880,11 +881,13 @@ struct aha_ccb *ccb; break; default: /* Other scsi protocol messes */ xs->error = XS_DRIVER_STUFFUP; +#ifdef AHADEBUG if (aha_debug > 1) { printf("host_stat%x\n", ccb->host_stat); } +#endif /*AHADEBUG*/ } } @@ -901,11 +904,13 @@ struct aha_ccb *ccb; xs->error = XS_BUSY; break; default: +#ifdef AHADEBUG if (aha_debug > 1) { printf("target_stat%x\n", ccb->target_stat); } +#endif /*AHADEBUG*/ xs->error = XS_DRIVER_STUFFUP; } } @@ -946,8 +951,10 @@ int unit; } if (i >= AHA_RESET_TIMEOUT) { +#ifdef AHADEBUG if (aha_debug) printf("aha_init: No answer from adaptec board\n"); +#endif /*AHADEBUG*/ return(ENXIO); } @@ -957,12 +964,12 @@ int unit; * level * \***********************************************/ #ifdef __386BSD__ + printf("aha%d reading board settings, ",unit); #define PRNT(x) #else __386BSD__ printf("aha%d:",unit); #define PRNT(x) printf(x) #endif __386BSD__ - DELAY(1000); /* for Bustek 545 */ aha_cmd(unit,0, sizeof(conf), 0 ,&conf, AHA_CONF_GET); switch(conf.chan) { @@ -1110,8 +1117,10 @@ struct scsi_xfer *xs; struct iovec *iovp; int s; +#ifdef AHADEBUG if(scsi_debug & PRINTROUTINES) printf("aha_scsi_cmd "); +#endif /*AHADEBUG*/ /***********************************************\ * get a ccb (mbox-out) to use. If the transfer * * is from a buf (possibly from interrupt time) * @@ -1175,10 +1184,12 @@ struct scsi_xfer *xs; { lto3b(iovp->iov_base,&(sg->seg_addr)); lto3b(iovp->iov_len,&(sg->seg_len)); +#ifdef AHADEBUG if(scsi_debug & SHOWSCATGATH) printf("(0x%x@0x%x)" ,iovp->iov_len ,iovp->iov_base); +#endif /*AHADEBUG*/ sg++; iovp++; seg++; @@ -1191,8 +1202,10 @@ struct scsi_xfer *xs; * Set up the scatter gather block * \***********************************************/ +#ifdef AHADEBUG if(scsi_debug & SHOWSCATGATH) printf("%d @0x%x:- ",xs->datalen,xs->data); +#endif /*AHADEBUG*/ datalen = xs->datalen; thiskv = (int)xs->data; thisphys = KVTOPHYS(thiskv); @@ -1204,8 +1217,10 @@ struct scsi_xfer *xs; /* put in the base address */ lto3b(thisphys,&(sg->seg_addr)); +#ifdef AHADEBUG if(scsi_debug & SHOWSCATGATH) printf("0x%x",thisphys); +#endif /*AHADEBUG*/ /* do it at least once */ nextphys = thisphys; @@ -1235,16 +1250,20 @@ struct scsi_xfer *xs; /***************************************\ * next page isn't contiguous, finish the seg* \***************************************/ +#ifdef AHADEBUG if(scsi_debug & SHOWSCATGATH) printf("(0x%x)",bytes_this_seg); +#endif /*AHADEBUG*/ lto3b(bytes_this_seg,&(sg->seg_len)); sg++; seg++; } } lto3b(seg * sizeof(struct aha_scat_gath),ccb->data_length); +#ifdef AHADEBUG if(scsi_debug & SHOWSCATGATH) printf("\n"); +#endif /*AHADEBUG*/ if (datalen) { /* there's still data, must have run out of segs! */ printf("aha_scsi_cmd%d: more than %d DMA segs\n", @@ -1266,6 +1285,7 @@ struct scsi_xfer *xs; \***********************************************/ if(!(flags & SCSI_RESET)) bcopy(xs->cmd, &ccb->scsi_cmd, ccb->scsi_cmd_length); +#ifdef AHADEBUG if(scsi_debug & SHOWCOMMANDS) { u_char *b = (u_char *)&ccb->scsi_cmd; @@ -1291,22 +1311,27 @@ struct scsi_xfer *xs; ); } } +#endif /*AHADEBUG*/ if (!(flags & SCSI_NOMASK)) { s= splbio(); /* stop instant timeouts */ - aha_add_timeout(ccb,xs->timeout); + timeout(aha_timeout,ccb,(xs->timeout * hz) / 1000); aha_startmbx(ccb->mbx); /***********************************************\ * Usually return SUCCESSFULLY QUEUED * \***********************************************/ splx(s); +#ifdef AHADEBUG if(scsi_debug & TRACEINTERRUPTS) printf("sent "); +#endif /*AHADEBUG*/ return(SUCCESSFULLY_QUEUED); } aha_startmbx(ccb->mbx); +#ifdef AHADEBUG if(scsi_debug & TRACEINTERRUPTS) printf("cmd_sent, waiting "); +#endif /*AHADEBUG*/ /***********************************************\ * If we can't use interrupts, poll on completion* \***********************************************/ @@ -1406,21 +1431,21 @@ int unit; { speed++; } -/* XXX printf("%d nSEC ok, use ",retval); */ + printf("%d nSEC ok, use ",retval); retval2 = aha_bus_speed_check(unit,speed); if(retval2 == HAD_ERROR) /* retval is slowest already */ { -/* XXX printf("marginal "); */ + printf("marginal "); retval2 = retval; } if(retval2) { -/* XXX printf("%d nSEC ",retval2); */ + printf("%d nSEC ",retval2); return(retval2); } else { -/* XXX printf(".. slower failed, abort.\n",retval); */ + printf(".. slower failed, abort.\n",retval); return(0); } @@ -1498,166 +1523,45 @@ int unit,speed; } -/* - * +----------+ +----------+ +----------+ - * aha_soonest--->| later |--->| later|--->| later|-->0 - * | [Delta] | | [Delta] | | [Delta] | - * 0<---|sooner |<---|sooner |<---|sooner |<---aha_latest - * +----------+ +----------+ +----------+ - * - * aha_furtherest = sum(Delta[1..n]) - */ -aha_add_timeout(ccb,time) -struct aha_ccb *ccb; -int time; + +aha_timeout(struct aha_ccb *ccb) { - int timeprev; - struct aha_ccb *prev; - int s = splbio(); - - if(prev = aha_latest) /* yes, an assign */ - { - timeprev = aha_furtherest; - } - else - { - timeprev = 0; - } - while(prev && (timeprev > time)) - { - timeprev -= prev->delta; - prev = prev->sooner; - } - if(prev) - { - ccb->delta = time - timeprev; - if( ccb->later = prev->later) /* yes an assign */ - { - ccb->later->sooner = ccb; - ccb->later->delta -= ccb->delta; - } - else - { - aha_furtherest = time; - aha_latest = ccb; - } - ccb->sooner = prev; - prev->later = ccb; - } - else - { - if( ccb->later = aha_soonest) /* yes, an assign*/ - { - ccb->later->sooner = ccb; - ccb->later->delta -= time; - } - else - { - aha_furtherest = time; - aha_latest = ccb; - } - ccb->delta = time; - ccb->sooner = (struct aha_ccb *)0; - aha_soonest = ccb; - } - splx(s); -} - -aha_remove_timeout(ccb) -struct aha_ccb *ccb; -{ - int s = splbio(); - - if(ccb->sooner) - { - ccb->sooner->later = ccb->later; - } - else - { - aha_soonest = ccb->later; - } - if(ccb->later) - { - ccb->later->sooner = ccb->sooner; - ccb->later->delta += ccb->delta; - } - else - { - aha_latest = ccb->sooner; - aha_furtherest -= ccb->delta; - } - ccb->sooner = ccb->later = (struct aha_ccb *)0; - splx(s); -} - - -extern int hz; -#define ONETICK 500 /* milliseconds */ -#define SLEEPTIME ((hz * ONETICK) / 1000) -aha_timeout(arg) -int arg; -{ - struct aha_ccb *ccb; int unit; int s = splbio(); - while( ccb = aha_soonest ) + unit = ccb->xfer->adapter; + printf("aha%d: device %d timed out ",unit + ,ccb->xfer->targ); + + /***************************************\ + * If The ccb's mbx is not free, then * + * the board has gone south * + \***************************************/ + if(ccb->mbx->cmd != AHA_MBO_FREE) { - if(ccb->delta <= ONETICK) - /***********************************************\ - * It has timed out, we need to do some work * - \***********************************************/ - { - unit = ccb->xfer->adapter; - printf("aha%d: device %d timed out ",unit - ,ccb->xfer->targ); - - /***************************************\ - * Unlink it from the queue * - \***************************************/ - aha_remove_timeout(ccb); - - /***************************************\ - * If The ccb's mbx is not free, then * - * the board has gone south * - \***************************************/ - if(ccb->mbx->cmd != AHA_MBO_FREE) - { - printf("aha%d not taking commands!\n" - ,unit); - Debugger(); - } - /***************************************\ - * If it has been through before, then * - * a previous abort has failed, don't * - * try abort again * - \***************************************/ - if(ccb->flags == CCB_ABORTED) /* abort timed out */ - { - printf(" AGAIN\n"); - ccb->xfer->retries = 0; /* I MEAN IT ! */ - ccb->host_stat = AHA_ABORTED; - aha_done(unit,ccb); - } - else /* abort the operation that has timed out */ - { - printf("\n"); - aha_abortmbx(ccb->mbx); - /* 2 secs for the abort */ - aha_add_timeout(ccb,2000 + ONETICK); - ccb->flags = CCB_ABORTED; - } - } - else - /***********************************************\ - * It has not timed out, adjust and leave * - \***********************************************/ - { - ccb->delta -= ONETICK; - aha_furtherest -= ONETICK; - break; - } + printf("aha%d not taking commands!\n" + ,unit); + Debugger(); + } + /***************************************\ + * If it has been through before, then * + * a previous abort has failed, don't * + * try abort again * + \***************************************/ + if(ccb->flags == CCB_ABORTED) /* abort timed out */ + { + printf(" AGAIN\n"); + ccb->xfer->retries = 0; /* I MEAN IT ! */ + ccb->host_stat = AHA_ABORTED; + aha_done(unit,ccb); + } + else /* abort the operation that has timed out */ + { + printf("\n"); + aha_abortmbx(ccb->mbx); + /* 2 secs for the abort */ + timeout(aha_timeout,ccb,2 * hz); + ccb->flags = CCB_ABORTED; } splx(s); - timeout(aha_timeout,arg,SLEEPTIME); } diff --git a/sys/i386/isa/aha1742.c b/sys/i386/isa/aha1742.c index 774e6f88e40..b4e4d98fac1 100644 --- a/sys/i386/isa/aha1742.c +++ b/sys/i386/isa/aha1742.c @@ -11,41 +11,15 @@ * TFS supplies this software to be publicly redistributed * on the understanding that TFS is not responsible for the correct * functioning of this software in any circumstances. - */ - -/* - * HISTORY - * $Log: aha1742.c,v $ - * Revision 1.4 1993/08/06 11:59:02 rgrimes - * Fixed **probing for scsi devices** message to have a controller and unit - * message on the begining of it: - * aha0: **probing for scsi devices** * - * Revision 1.3 1993/07/29 11:55:34 nate - * Syncing our sources back with Julian's, and removing PATCHKIT headers. * - * Large Bustek changes, most everything else is minimal. + * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE + * -------------------- ----- ---------------------- + * CURRENT PATCH LEVEL: 1 00098 + * -------------------- ----- ---------------------- * - * Revision 1.2 1993/07/15 17:52:58 davidg - * Modified attach printf's so that the output is compatible with the "new" - * way of doing things. There still remain several drivers that need to - * be updated. Also added a compile-time option to pccons to switch the - * control and caps-lock keys (REVERSE_CAPS_CTRL) - added for my personal - * sanity. - * - * Revision 1.1.1.1 1993/06/12 14:57:59 rgrimes - * Initial import, 0.1 + pk 0.2.4-B1 - * - * julian - removed un-necessary splx() calls and debugging code - * - * Revision 1.3 93/05/22 16:51:18 julian - * set up dev->dev_pic before it's needed for OSF - * - * Revision 1.2 93/05/07 11:40:27 julian - * fixed SLEEPTIME calculation - * - * Revision 1.1 93/05/07 11:14:03 julian - * Initial revision + * 16 Feb 93 Julian Elischer ADDED for SCSI system + * commenced: Sun Sep 27 18:14:01 PDT 1992 */ #include @@ -103,6 +77,7 @@ int Debugger(); #endif MACH typedef unsigned long int physaddr; +extern int hz; #ifdef MACH extern physaddr kvtophys(); @@ -297,8 +272,6 @@ struct ecb /*-----------------end of hardware supported fields----------------*/ struct ecb *next; /* in free list */ struct scsi_xfer *xs; /* the scsi_xfer for this cmd */ - long int delta; /* difference from previous*/ - struct ecb *later,*sooner; int flags; #define ECB_FREE 0 #define ECB_ACTIVE 1 @@ -310,9 +283,6 @@ struct ecb struct scsi_sense_data ecb_sense; }; -struct ecb *ahb_soonest = (struct ecb *)0; -struct ecb *ahb_latest = (struct ecb *)0; -long int ahb_furtherest = 0; /* longest time in the timeout queue */ /* */ struct ahb_data @@ -546,6 +516,7 @@ struct isa_dev *dev; #ifdef __386BSD__ /* 386BSD */ dev->id_irq = (1 << ahb_data[unit].vect); dev->id_drq = -1; /* use EISA dma */ + printf("\n **"); #endif __386BSD__ ahb_unit++; @@ -562,7 +533,7 @@ struct isa_dev *dev; #ifdef __386BSD__ - printf("ahb%d: **probing for scsi devices**\n", unit); + printf(" probing for scsi devices**\n"); #endif __386BSD__ /***********************************************\ @@ -572,10 +543,9 @@ struct isa_dev *dev; #if defined(OSF) ahb_attached[unit]=1; #endif /* defined(OSF) */ - if(!unit) /* only one for all boards */ - { - ahb_timeout(0); - } +#ifdef __386BSD__ + printf("ahb%d",unit); +#endif __386BSD__ return; } @@ -603,8 +573,10 @@ ahbintr(unit) int port = ahb_data[unit].baseport; +#ifdef AHBDEBUG if(scsi_debug & PRINTROUTINES) printf("ahbintr "); +#endif /*AHBDEBUG*/ #if defined(OSF) if (!ahb_attached[unit]) @@ -623,8 +595,10 @@ ahbintr(unit) stat = ahbstat & G2INTST_INT_STAT; mboxval = inl(port + MBOXIN0);/* don't know this will work */ outb(port + G2CNTRL, G2CNTRL_CLEAR_EISA_INT); +#ifdef AHBDEBUG if(scsi_debug & TRACEINTERRUPTS) printf("status = 0x%x ",stat); +#endif /*AHBDEBUG*/ /***********************************************\ * Process the completed operation * \***********************************************/ @@ -647,13 +621,9 @@ ahbintr(unit) ahb_data[unit].immed_ecb = 0; break; case AHB_ASN: /* for target mode */ - printf("ahb%d: Unexpected ASN interrupt(%x)\n", - unit, mboxval); ecb = 0; break; case AHB_HW_ERR: - printf("ahb%d: Hardware error interrupt(%x)\n", - unit, mboxval); ecb = 0; break; case AHB_ECB_RECOVERED: @@ -669,13 +639,15 @@ ahbintr(unit) } if(ecb) { +#ifdef AHBDEBUG if(ahb_debug & AHB_SHOWCMDS ) { ahb_show_scsi_cmd(ecb->xs); } if((ahb_debug & AHB_SHOWECBS) && ecb) printf("",ecb); - ahb_remove_timeout(ecb); +#endif /*AHBDEBUG*/ + untimeout(ahb_timeout,ecb); ahb_done(unit,ecb,((stat == AHB_ECB_OK)?SUCCESS:FAIL)); } } @@ -695,8 +667,10 @@ struct ecb *ecb; struct scsi_sense_data *s1,*s2; struct scsi_xfer *xs = ecb->xs; +#ifdef AHBDEBUG if(scsi_debug & (PRINTROUTINES | TRACEINTERRUPTS)) printf("ahb_done "); +#endif /*AHBDEBUG*/ /***********************************************\ * Otherwise, put the results of the operation * * into the xfer and call whoever started it * @@ -732,19 +706,23 @@ struct ecb *ecb; case HS_CMD_ABORTED_ADAPTER: /* No response */ break; case HS_TIMED_OUT: /* No response */ +#ifdef AHBDEBUG if (ahb_debug & AHB_SHOWMISC) { printf("timeout reported back\n"); } +#endif /*AHBDEBUG*/ xs->error = XS_TIMEOUT; break; default: /* Other scsi protocol messes */ xs->error = XS_DRIVER_STUFFUP; +#ifdef AHBDEBUG if (ahb_debug & AHB_SHOWMISC) { printf("unexpected ha_status: %x\n", stat->ha_status); } +#endif /*AHBDEBUG*/ } } @@ -761,11 +739,13 @@ struct ecb *ecb; xs->error = XS_BUSY; break; default: +#ifdef AHBDEBUG if (ahb_debug & AHB_SHOWMISC) { printf("unexpected targ_status: %x\n", stat->targ_status); } +#endif /*AHBDEBUG*/ xs->error = XS_DRIVER_STUFFUP; } } @@ -785,8 +765,10 @@ struct ecb *ecb; { unsigned int opri; +#ifdef AHBDEBUG if(scsi_debug & PRINTROUTINES) printf("ecb%d(0x%x)> ",unit,flags); +#endif /*AHBDEBUG*/ if (!(flags & SCSI_NOMASK)) opri = splbio(); @@ -813,8 +795,10 @@ ahb_get_ecb(unit,flags) unsigned opri; struct ecb *rc; +#ifdef AHBDEBUG if(scsi_debug & PRINTROUTINES) printf("",ecb); if(scsi_debug & SHOWCOMMANDS) { ahb_show_scsi_cmd(xs); } +#endif /*AHBDEBUG*/ ecb->xs = xs; /***********************************************\ * If it's a reset, we need to do an 'immediate' * @@ -1039,7 +1030,7 @@ cheat = ecb; { s = splbio(); ahb_send_immed(unit,xs->targ,AHB_TARG_RESET); - ahb_add_timeout(ecb,xs->timeout); + timeout(ahb_timeout,ecb,(xs->timeout * hz)/1000); splx(s); return(SUCCESSFULLY_QUEUED); } @@ -1049,8 +1040,10 @@ cheat = ecb; /***********************************************\ * If we can't use interrupts, poll on completion* \***********************************************/ +#ifdef AHBDEBUG if(scsi_debug & TRACEINTERRUPTS) printf("wait "); +#endif /*AHBDEBUG*/ if( ahb_poll(unit,xs->timeout)) { ahb_free_ecb(unit,ecb,flags); @@ -1089,10 +1082,12 @@ cheat = ecb; { sg->addr = (physaddr)iovp->iov_base; xs->datalen += sg->len = iovp->iov_len; +#ifdef AHBDEBUG if(scsi_debug & SHOWSCATGATH) printf("(0x%x@0x%x)" ,iovp->iov_len ,iovp->iov_base); +#endif /*AHBDEBUG*/ sg++; iovp++; seg++; @@ -1105,8 +1100,10 @@ cheat = ecb; * Set up the scatter gather block * \***********************************************/ +#ifdef AHBDEBUG if(scsi_debug & SHOWSCATGATH) printf("%d @0x%x:- ",xs->datalen,xs->data); +#endif /*AHBDEBUG*/ datalen = xs->datalen; thiskv = (int)xs->data; thisphys = KVTOPHYS(thiskv); @@ -1118,8 +1115,10 @@ cheat = ecb; /* put in the base address */ sg->addr = thisphys; +#ifdef AHBDEBUG if(scsi_debug & SHOWSCATGATH) printf("0x%x",thisphys); +#endif /*AHBDEBUG*/ /* do it at least once */ nextphys = thisphys; @@ -1148,16 +1147,20 @@ cheat = ecb; /********************************************\ * next page isn't contiguous, finish the seg * \********************************************/ +#ifdef AHBDEBUG if(scsi_debug & SHOWSCATGATH) printf("(0x%x)",bytes_this_seg); +#endif /*AHBDEBUG*/ sg->len = bytes_this_seg; sg++; seg++; } } /*end of iov/kv decision */ ecb->datalen = seg * sizeof(struct ahb_dma_seg); +#ifdef AHBDEBUG if(scsi_debug & SHOWSCATGATH) printf("\n"); +#endif /*AHBDEBUG*/ if (datalen) { /* there's still data, must have run out of segs! */ printf("ahb_scsi_cmd%d: more than %d DMA segs\n", @@ -1185,18 +1188,22 @@ cheat = ecb; { s = splbio(); ahb_send_mbox(unit,OP_START_ECB,xs->targ,ecb); - ahb_add_timeout(ecb,xs->timeout); + timeout(ahb_timeout,ecb,(xs->timeout * hz)/1000); splx(s); +#ifdef AHBDEBUG if(scsi_debug & TRACEINTERRUPTS) printf("cmd_sent "); +#endif /*AHBDEBUG*/ return(SUCCESSFULLY_QUEUED); } /***********************************************\ * If we can't use interrupts, poll on completion* \***********************************************/ ahb_send_mbox(unit,OP_START_ECB,xs->targ,ecb); +#ifdef AHBDEBUG if(scsi_debug & TRACEINTERRUPTS) printf("cmd_wait "); +#endif /*AHBDEBUG*/ do { if(ahb_poll(unit,xs->timeout)) @@ -1219,172 +1226,55 @@ cheat = ecb; return(COMPLETE); } -/* - * +----------+ +----------+ +----------+ - * ahb_soonest--->| later |--->| later|--->| later|--->0 - * | [Delta] | | [Delta] | | [Delta] | - * 0<---|sooner |<---|sooner |<---|sooner |<---ahb_latest - * +----------+ +----------+ +----------+ - * - * ahb_furtherest = sum(Delta[1..n]) - */ -ahb_add_timeout(ecb,time) -struct ecb *ecb; -int time; + +ahb_timeout(struct ecb *ecb) { - int timeprev; - struct ecb *prev; - int s = splbio(); - - if(prev = ahb_latest) /* yes, an assign */ - { - timeprev = ahb_furtherest; - } - else - { - timeprev = 0; - } - while(prev && (timeprev > time)) - { - timeprev -= prev->delta; - prev = prev->sooner; - } - if(prev) - { - ecb->delta = time - timeprev; - if( ecb->later = prev->later) /* yes an assign */ - { - ecb->later->sooner = ecb; - ecb->later->delta -= ecb->delta; - } - else - { - ahb_furtherest = time; - ahb_latest = ecb; - } - ecb->sooner = prev; - prev->later = ecb; - } - else - { - if( ecb->later = ahb_soonest) /* yes, an assign*/ - { - ecb->later->sooner = ecb; - ecb->later->delta -= time; - } - else - { - ahb_furtherest = time; - ahb_latest = ecb; - } - ecb->delta = time; - ecb->sooner = (struct ecb *)0; - ahb_soonest = ecb; - } - splx(s); -} - -ahb_remove_timeout(ecb) -struct ecb *ecb; -{ - int s = splbio(); - - if(ecb->sooner) - { - ecb->sooner->later = ecb->later; - } - else - { - ahb_soonest = ecb->later; - } - if(ecb->later) - { - ecb->later->sooner = ecb->sooner; - ecb->later->delta += ecb->delta; - } - else - { - ahb_latest = ecb->sooner; - ahb_furtherest -= ecb->delta; - } - ecb->sooner = ecb->later = (struct ecb *)0; - splx(s); -} - - -extern int hz; -#define ONETICK 500 /* milliseconds */ -#define SLEEPTIME ((hz * ONETICK) / 1000) -ahb_timeout(arg) -int arg; -{ - struct ecb *ecb; int unit; int s = splbio(); - while( ecb = ahb_soonest ) + unit = ecb->xs->adapter; + printf("ahb%d:%d device timed out\n",unit + ,ecb->xs->targ); +#ifdef AHBDEBUG + if(ahb_debug & AHB_SHOWECBS) + ahb_print_active_ecb(unit); +#endif /*AHBDEBUG*/ + + /***************************************\ + * If it's immediate, don't try abort it * + \***************************************/ + if(ecb->flags & ECB_IMMED) { - if(ecb->delta <= ONETICK) - /***********************************************\ - * It has timed out, we need to do some work * - \***********************************************/ - { - unit = ecb->xs->adapter; - printf("ahb%d:%d device timed out\n",unit - ,ecb->xs->targ); - if(ahb_debug & AHB_SHOWECBS) - ahb_print_active_ecb(); - - /***************************************\ - * Unlink it from the queue * - \***************************************/ - ahb_remove_timeout(ecb); - - /***************************************\ - * If it's immediate, don't try abort it * - \***************************************/ - if(ecb->flags & ECB_IMMED) - { - ecb->xs->retries = 0; /* I MEAN IT ! */ - ecb->flags |= ECB_IMMED_FAIL; - ahb_done(unit,ecb,FAIL); - continue; - } - /***************************************\ - * If it has been through before, then * - * a previous abort has failed, don't * - * try abort again * - \***************************************/ - if(ecb->flags == ECB_ABORTED) /* abort timed out */ - { - printf("AGAIN"); - ecb->xs->retries = 0; /* I MEAN IT ! */ - ecb->ecb_status.ha_status = HS_CMD_ABORTED_HOST; - ahb_done(unit,ecb,FAIL); - } - else /* abort the operation that has timed out */ - { - printf("\n"); - ahb_send_mbox(unit,OP_ABORT_ECB,ecb->xs->targ,ecb); - /* 2 secs for the abort */ - ahb_add_timeout(ecb,2000 + ONETICK); - ecb->flags = ECB_ABORTED; - } - } - else - /***********************************************\ - * It has not timed out, adjust and leave * - \***********************************************/ - { - ecb->delta -= ONETICK; - ahb_furtherest -= ONETICK; - break; - } + ecb->xs->retries = 0; /* I MEAN IT ! */ + ecb->flags |= ECB_IMMED_FAIL; + ahb_done(unit,ecb,FAIL); + splx(s); + return; + } + /***************************************\ + * If it has been through before, then * + * a previous abort has failed, don't * + * try abort again * + \***************************************/ + if(ecb->flags == ECB_ABORTED) /* abort timed out */ + { + printf("AGAIN"); + ecb->xs->retries = 0; /* I MEAN IT ! */ + ecb->ecb_status.ha_status = HS_CMD_ABORTED_HOST; + ahb_done(unit,ecb,FAIL); + } + else /* abort the operation that has timed out */ + { + printf("\n"); + ahb_send_mbox(unit,OP_ABORT_ECB,ecb->xs->targ,ecb); + /* 2 secs for the abort */ + timeout(ahb_timeout,ecb,2 * hz); + ecb->flags = ECB_ABORTED; } splx(s); - timeout(ahb_timeout,arg,SLEEPTIME); } +#ifdef AHBDEBUG ahb_show_scsi_cmd(struct scsi_xfer *xs) { u_char *b = (u_char *)xs->cmd; @@ -1419,24 +1309,26 @@ struct ecb *ecb; ,ecb->opcode ,ecb->cdblen ,ecb->senselen); - printf(" datlen:%d hstat:%x tstat:%x delta:%d flags:%x\n" + printf(" datlen:%d hstat:%x tstat:%x flags:%x\n" ,ecb->datalen ,ecb->ecb_status.ha_status ,ecb->ecb_status.targ_status - ,ecb->delta ,ecb->flags); ahb_show_scsi_cmd(ecb->xs); } -ahb_print_active_ecb() +ahb_print_active_ecb(int unit) { - struct ecb *ecb; - ecb = ahb_soonest; + struct ecb *ecb = ahb_data[unit].ecbs; + int i = NUM_CONCURRENT; - while(ecb) + while(i--) { - ahb_print_ecb(ecb); - ecb = ecb->later; + if(ecb->flags != ECB_FREE) + { + ahb_print_ecb(ecb); + } + ecb++; } - printf("Furtherest = %d\n",ahb_furtherest); } +#endif /*AHBDEBUG */ diff --git a/sys/i386/isa/bt742a.c b/sys/i386/isa/bt742a.c index d428094911d..d6d49fffd38 100644 --- a/sys/i386/isa/bt742a.c +++ b/sys/i386/isa/bt742a.c @@ -13,31 +13,32 @@ * functioning of this software in any circumstances. * * + * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE + * -------------------- ----- ---------------------- + * CURRENT PATCH LEVEL: 1 00098 + * -------------------- ----- ---------------------- + * + * 16 Feb 93 Julian Elischer ADDED for SCSI system */ /* * HISTORY - * $Log: bt742a.c,v $ - * Revision 1.2 1993/07/29 11:55:35 nate - * Syncing our sources back with Julian's, and removing PATCHKIT headers. - * - * Large Bustek changes, most everything else is minimal. - * - * Revision 1.1.1.1 1993/06/12 14:57:58 rgrimes - * Initial import, 0.1 + pk 0.2.4-B1 - * - * Revision 1.11 93/05/27 13:39:52 julian + * $Log: bt742a.c,v $ + * Revision 1.12 93/08/07 13:20:44 julian + * replace private timeout stuff with system timeout calls. + * + * Revision 1.11 93/05/27 13:39:52 root * Enable mail box round-robin scheme by new host adapter command appeared * at FirmWare V3.31 ( This release is shipped without testing at V3.31 ) * - * Revision 1.10 93/05/22 16:38:22 julian + * Revision 1.10 93/05/22 16:38:22 root * under OSF, the dev_pic must be set up before it's used. * was only done ifndef OSF. * - * Revision 1.9 93/05/07 11:37:24 julian + * Revision 1.9 93/05/07 11:37:24 root * fix SLEEPTIME calculation. * - * Revision 1.8 93/05/07 11:27:00 julian + * Revision 1.8 93/05/07 11:27:00 root * Merge with 1.7.1 * * Revision 1.7.1 1993/01/01 04:01:02 amurai @@ -131,6 +132,7 @@ int Debugger(); int Debugger(); #endif MACH +extern int hz; extern int delaycount; /* from clock setup code */ typedef unsigned long int physaddr; @@ -309,17 +311,12 @@ struct bt_ccb { /*------------------------------------longword boundary */ struct bt_mbx_out *mbx; /* pointer to mail box */ /*------------------------------------longword boundary */ - long int delta; /* difference from previous*/ - struct bt_ccb *later,*sooner; int flags; #define CCB_FREE 0 #define CCB_ACTIVE 1 #define CCB_ABORTED 2 }; -struct bt_ccb *bt_soonest = (struct bt_ccb *)0; -struct bt_ccb *bt_latest = (struct bt_ccb *)0; -long int bt_furtherest = 0; /* longest time in the timeout queue */ /* * opcode fields */ @@ -684,7 +681,7 @@ struct isa_dev *dev; #ifdef __386BSD__ - printf("bt%d: **probing for scsi devices**\n", unit); + printf(" probing for scsi devices**\n"); #endif __386BSD__ /***********************************************\ @@ -694,10 +691,6 @@ struct isa_dev *dev; #if defined(OSF) bt_attached[unit]=1; #endif /* defined(OSF) */ - if(!unit) /* only one for all boards */ - { - bt_timeout(0); - } #ifdef __386BSD__ printf("bt%d",unit); #endif __386BSD__ @@ -822,7 +815,7 @@ AGAIN: wmbi->stat = BT_MBI_FREE; if(ccb) { - bt_remove_timeout(ccb); + untimeout(bt_timeout,ccb); bt_done(unit,ccb); } @@ -1537,7 +1530,7 @@ struct scsi_xfer *xs; #endif if (!(flags & SCSI_NOMASK)) { - bt_add_timeout(ccb,xs->timeout); + timeout(bt_timeout,ccb,(xs->timeout * hz) / 1000); return(SUCCESSFULLY_QUEUED); } else /***********************************************\ @@ -1610,174 +1603,57 @@ struct scsi_xfer *xs; } } -/* - * +----------+ +----------+ +----------+ - * bt_soonest--->| later |---->| later|---->| later|--->0 - * | [Delta] | | [Delta] | | [Delta] | - * 0<-----|sooner |<----|sooner |<----|sooner |<----bt_latest - * +----------+ +----------+ +----------+ - * - * bt_furtherest = sum(Delta[1..n]) - */ -bt_add_timeout(ccb,time) -struct bt_ccb *ccb; -int time; + +bt_timeout(struct bt_ccb *ccb) { - int timeprev; - struct bt_ccb *prev; - int s = splbio(); - - if(prev = bt_latest) /* yes, an assign */ - { - timeprev = bt_furtherest; - } - else - { - timeprev = 0; - } - while(prev && (timeprev > time)) - { - timeprev -= prev->delta; - prev = prev->sooner; - } - if(prev) - { - ccb->delta = time - timeprev; - if( ccb->later = prev->later) /* yes an assign */ - { - ccb->later->sooner = ccb; - ccb->later->delta -= ccb->delta; - } - else - { - bt_furtherest = time; - bt_latest = ccb; - } - ccb->sooner = prev; - prev->later = ccb; - } - else - { - if( ccb->later = bt_soonest) /* yes, an assign*/ - { - ccb->later->sooner = ccb; - ccb->later->delta -= time; - } - else - { - bt_furtherest = time; - bt_latest = ccb; - } - ccb->delta = time; - ccb->sooner = (struct bt_ccb *)0; - bt_soonest = ccb; - } - splx(s); -} - -bt_remove_timeout(ccb) -struct bt_ccb *ccb; -{ - int s = splbio(); - - if(ccb->sooner) - { - ccb->sooner->later = ccb->later; - } - else - { - bt_soonest = ccb->later; - } - if(ccb->later) - { - ccb->later->sooner = ccb->sooner; - ccb->later->delta += ccb->delta; - } - else - { - bt_latest = ccb->sooner; - bt_furtherest -= ccb->delta; - } - ccb->sooner = ccb->later = (struct bt_ccb *)0; - splx(s); -} - - -extern int hz; -#define ONETICK 500 /* milliseconds */ -#define SLEEPTIME ((hz * ONETICK) / 1000) -bt_timeout(arg) -int arg; -{ - struct bt_ccb *ccb; int unit; int s = splbio(); - while( ccb = bt_soonest ) - { - if(ccb->delta <= ONETICK) - /***********************************************\ - * It has timed out, we need to do some work * - \***********************************************/ - { - unit = ccb->xfer->adapter; - printf("bt%d:%d device timed out\n",unit - ,ccb->xfer->targ); - if(bt_debug & BT_SHOWCCBS) - tfs_print_active_ccbs(); + unit = ccb->xfer->adapter; + printf("bt%d:%d device timed out\n",unit + ,ccb->xfer->targ); +#ifdef UTEST + if(bt_debug & BT_SHOWCCBS) + bt_print_active_ccbs(unit); +#endif - /***************************************\ - * Unlink it from the queue * - \***************************************/ - bt_remove_timeout(ccb); - /***************************************\ - * If The ccb's mbx is not free, then * - * the board has gone Far East ? * - \***************************************/ - if((struct bt_ccb *)PHYSTOKV(ccb->mbx->ccb_addr)==ccb && - ccb->mbx->cmd != BT_MBO_FREE ) - { - printf("bt%d not taking commands!\n" - ,unit); - Debugger(); - } - /***************************************\ - * If it has been through before, then * - * a previous abort has failed, don't * - * try abort again * - \***************************************/ - if(ccb->flags == CCB_ABORTED) /* abort timed out */ - { - printf("Abort Operation has timed out.\n"); - ccb->xfer->retries = 0; /* I MEAN IT ! */ - ccb->host_stat = BT_ABORTED; - bt_done(unit,ccb); - } - else /* abort the operation that has timed out */ - { - printf("Try to abort\n"); - bt_send_mbo( unit, ~SCSI_NOMASK, - BT_MBO_ABORT, ccb ); - /* 2 secs for the abort */ - bt_add_timeout(ccb,2000 + ONETICK); - ccb->flags = CCB_ABORTED; - } - } - else - /***********************************************\ - * It has not timed out, adjust and leave * - \***********************************************/ - { - ccb->delta -= ONETICK; - bt_furtherest -= ONETICK; - break; - } + /***************************************\ + * If The ccb's mbx is not free, then * + * the board has gone Far East ? * + \***************************************/ + if((struct bt_ccb *)PHYSTOKV(ccb->mbx->ccb_addr)==ccb && + ccb->mbx->cmd != BT_MBO_FREE ) + { + printf("bt%d not taking commands!\n" + ,unit); + Debugger(); + } + /***************************************\ + * If it has been through before, then * + * a previous abort has failed, don't * + * try abort again * + \***************************************/ + if(ccb->flags == CCB_ABORTED) /* abort timed out */ + { + printf("Abort Operation has timed out.\n"); + ccb->xfer->retries = 0; /* I MEAN IT ! */ + ccb->host_stat = BT_ABORTED; + bt_done(unit,ccb); + } + else /* abort the operation that has timed out */ + { + printf("Try to abort\n"); + bt_send_mbo( unit, ~SCSI_NOMASK, + BT_MBO_ABORT, ccb ); + /* 2 secs for the abort */ + timeout(bt_timeout,ccb,2 * hz); + ccb->flags = CCB_ABORTED; } splx(s); - timeout(bt_timeout,arg,SLEEPTIME); } -tfs_print_ccb(ccb) +#ifdef UTEST +bt_print_ccb(ccb) struct bt_ccb *ccb; { printf("ccb:%x op:%x cmdlen:%d senlen:%d\n" @@ -1785,23 +1661,24 @@ struct bt_ccb *ccb; ,ccb->opcode ,ccb->scsi_cmd_length ,ccb->req_sense_length); - printf(" datlen:%d hstat:%x tstat:%x delta:%d flags:%x\n" + printf(" datlen:%d hstat:%x tstat:%x flags:%x\n" ,ccb->data_length ,ccb->host_stat ,ccb->target_stat - ,ccb->delta ,ccb->flags); } -tfs_print_active_ccbs() +bt_print_active_ccbs(int unit) { struct bt_ccb *ccb; - ccb = bt_soonest; + ccb = &(bt_ccb[unit][0]); + int i = BT_CCB_SIZE; - while(ccb) + while(i--) { - tfs_print_ccb(ccb); - ccb = ccb->later; + if(ccb->flags != CCB_FREE) + bt_print_ccb(ccb); + ccb++; } - printf("Furtherest = %d\n",bt_furtherest); } +#endif /*UTEST*/ diff --git a/sys/i386/isa/ultra14f.c b/sys/i386/isa/ultra14f.c index dd8cd2c5962..17807436f20 100644 --- a/sys/i386/isa/ultra14f.c +++ b/sys/i386/isa/ultra14f.c @@ -16,20 +16,13 @@ * functioning of this software in any circumstances. * * - */ - -/* - * HISTORY - * $Log: ultra14f.c,v $ - * Revision 1.3 1993/07/29 11:55:37 nate - * Syncing our sources back with Julian's, and removing PATCHKIT headers. - * - * Large Bustek changes, most everything else is minimal. - * - * - * Revision 1.1 93/05/07 11:37:24 julian - * fix SLEEPTIME calculation. + * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE + * -------------------- ----- ---------------------- + * CURRENT PATCH LEVEL: 1 00098 + * -------------------- ----- ---------------------- * + * 16 Feb 93 Julian Elischer ADDED for SCSI system + * commenced: Sun Sep 27 18:14:01 PDT 1992 * slight mod to make work with 34F as well: Wed Jun 2 18:05:48 WST 1993 */ @@ -102,6 +95,7 @@ extern physaddr kvtophys(); #define KVTOPHYS(x) vtophys(x) #endif __386BSD__ +extern int hz; extern int delaycount; /* from clock setup code */ #define NUM_CONCURRENT 16 /* number of concurrent ops per board */ #define UHA_NSEG 33 /* number of dma segments supported */ @@ -251,8 +245,6 @@ struct mscp /*-----------------end of hardware supported fields----------------*/ struct mscp *next; /* in free list */ struct scsi_xfer *xs; /* the scsi_xfer for this cmd */ - long int delta; /* difference from previous*/ - struct mscp *later,*sooner; int flags; #define MSCP_FREE 0 #define MSCP_ACTIVE 1 @@ -261,9 +253,6 @@ struct mscp struct scsi_sense_data mscp_sense; }; -struct mscp *uha_soonest = (struct mscp *)0; -struct mscp *uha_latest = (struct mscp *)0; -long int uha_furtherest = 0; /* longest time in the timeout queue */ /* */ struct uha_data @@ -300,7 +289,9 @@ struct isa_driver uhadriver = { uhaprobe, uha_attach, "uha"}; #endif __386BSD__ static uha_unit = 0; +#ifdef UHADEBUG int uha_debug = 0; +#endif /*UHADEBUG*/ #define UHA_SHOWMSCPS 0x01 #define UHA_SHOWINTS 0x02 #define UHA_SHOWCMDS 0x04 @@ -458,7 +449,7 @@ struct isa_dev *dev; #ifdef __386BSD__ - printf("uha%d: **probing for scsi devices**\n", unit); + printf(" probing for scsi devices**\n"); #endif __386BSD__ /***********************************************\ @@ -469,11 +460,6 @@ struct isa_dev *dev; #if defined(OSF) uha_attached[unit]=1; #endif /* defined(OSF) */ - if(!unit) /* only one for all boards */ - { - uha_timeout(0); - } - #ifdef __386BSD__ printf("uha%d",unit); @@ -503,8 +489,10 @@ uhaintr(unit) int port = uha_data[unit].baseport; +#ifdef UHADEBUG if(scsi_debug & PRINTROUTINES) printf("uhaintr "); +#endif /*UHADEBUG*/ #if defined(OSF) if (!uha_attached[unit]) @@ -522,21 +510,25 @@ uhaintr(unit) mboxval = inl(port + UHA_ICM0); outb(port + UHA_SINT,UHA_ICM_ACK); +#ifdef UHADEBUG if(scsi_debug & TRACEINTERRUPTS) printf("status = 0x%x ",uhastat); +#endif /*UHADEBUG*/ /***********************************************\ * Process the completed operation * \***********************************************/ mscp = (struct mscp *)(PHYSTOKV(mboxval)); +#ifdef UHADEBUG if(uha_debug & UHA_SHOWCMDS ) { uha_show_scsi_cmd(mscp->xs); } if((uha_debug & UHA_SHOWMSCPS) && mscp) printf("",mscp); - uha_remove_timeout(mscp); +#endif /*UHADEBUG*/ + untimeout(uha_timeout,mscp); uha_done(unit,mscp); } @@ -556,8 +548,10 @@ struct mscp *mscp; struct scsi_sense_data *s1,*s2; struct scsi_xfer *xs = mscp->xs; +#ifdef UHADEBUG if(scsi_debug & (PRINTROUTINES | TRACEINTERRUPTS)) printf("uha_done "); +#endif /*UHADEBUG*/ /***********************************************\ * Otherwise, put the results of the operation * * into the xfer and call whoever started it * @@ -578,33 +572,41 @@ struct mscp *mscp; switch(mscp->ha_status) { case UHA_SBUS_TIMEOUT: /* No response */ +#ifdef UHADEBUG if (uha_debug & UHA_SHOWMISC) { printf("timeout reported back\n"); } +#endif /*UHADEBUG*/ xs->error = XS_TIMEOUT; break; case UHA_SBUS_OVER_UNDER: +#ifdef UHADEBUG if (uha_debug & UHA_SHOWMISC) { printf("scsi bus xfer over/underrun\n"); } +#endif /*UHADEBUG*/ xs->error = XS_DRIVER_STUFFUP; break; case UHA_BAD_SG_LIST: +#ifdef UHADEBUG if (uha_debug & UHA_SHOWMISC) { printf("bad sg list reported back\n"); } +#endif /*UHADEBUG*/ xs->error = XS_DRIVER_STUFFUP; break; default: /* Other scsi protocol messes */ xs->error = XS_DRIVER_STUFFUP; +#ifdef UHADEBUG if (uha_debug & UHA_SHOWMISC) { printf("unexpected ha_status: %x\n", mscp->ha_status); } +#endif /*UHADEBUG*/ } } @@ -619,11 +621,13 @@ struct mscp *mscp; \**************************************************************************/ { +#ifdef UHADEBUG if (uha_debug & UHA_SHOWMISC) { printf("unexpected targ_status: %x\n", mscp->targ_status); } +#endif /*UHADEBUG*/ xs->error = XS_DRIVER_STUFFUP; } } @@ -643,8 +647,10 @@ struct mscp *mscp; { unsigned int opri; +#ifdef UHADEBUG if(scsi_debug & PRINTROUTINES) printf("mscp%d(0x%x)> ",unit,flags); +#endif /*UHADEBUG*/ if (!(flags & SCSI_NOMASK)) opri = splbio(); @@ -671,8 +677,10 @@ uha_get_mscp(unit,flags) unsigned opri; struct mscp *rc; +#ifdef UHADEBUG if(scsi_debug & PRINTROUTINES) printf("",mscp); if(scsi_debug & SHOWCOMMANDS) { uha_show_scsi_cmd(xs); } +#endif /*UHADEBUG*/ mscp->xs = xs; /***********************************************\ * Put all the arguments for the xfer in the mscp * @@ -952,10 +964,12 @@ cheat = mscp; sg->addr.addr[2] = ((scratch >> 16) & 0xff); sg->addr.addr[3] = ((scratch >> 24) & 0xff); xs->datalen += *(unsigned long *)sg->len.len = iovp->iov_len; +#ifdef UHADEBUG if(scsi_debug & SHOWSCATGATH) printf("(0x%x@0x%x)" ,iovp->iov_len ,iovp->iov_base); +#endif /*UHADEBUG*/ sg++; iovp++; seg++; @@ -968,8 +982,10 @@ cheat = mscp; * Set up the scatter gather block * \***********************************************/ +#ifdef UHADEBUG if(scsi_debug & SHOWSCATGATH) printf("%d @0x%x:- ",xs->datalen,xs->data); +#endif /*UHADEBUG*/ datalen = xs->datalen; thiskv = (int)xs->data; thisphys = KVTOPHYS(thiskv); @@ -985,8 +1001,10 @@ cheat = mscp; sg->addr.addr[2] = ((thisphys >> 16) & 0xff); sg->addr.addr[3] = ((thisphys >> 24) & 0xff); +#ifdef UHADEBUG if(scsi_debug & SHOWSCATGATH) printf("0x%x",thisphys); +#endif /*UHADEBUG*/ /* do it at least once */ nextphys = thisphys; @@ -1015,8 +1033,10 @@ cheat = mscp; /********************************************\ * next page isn't contiguous, finish the seg * \********************************************/ +#ifdef UHADEBUG if(scsi_debug & SHOWSCATGATH) printf("(0x%x)",bytes_this_seg); +#endif /*UHADEBUG*/ sg->len.len[0] = (bytes_this_seg & 0xff); sg->len.len[1] = ((bytes_this_seg >> 8) & 0xff); sg->len.len[2] = ((bytes_this_seg >> 16) & 0xff); @@ -1032,8 +1052,10 @@ cheat = mscp; mscp->datalen.len[3] = ((templen >> 24) & 0xff); mscp->sg_num = seg; +#ifdef UHADEBUG if(scsi_debug & SHOWSCATGATH) printf("\n"); +#endif /*UHADEBUG*/ if (datalen) { /* there's still data, must have run out of segs! */ printf("uha_scsi_cmd%d: more than %d DMA segs\n", @@ -1071,18 +1093,22 @@ cheat = mscp; { s = splbio(); uha_send_mbox(unit,mscp); - uha_add_timeout(mscp,xs->timeout); + timeout(uha_timeout,mscp,(xs->timeout * hz) / 1000); splx(s); +#ifdef UHADEBUG if(scsi_debug & TRACEINTERRUPTS) printf("cmd_sent "); +#endif /*UHADEBUG*/ return(SUCCESSFULLY_QUEUED); } /***********************************************\ * If we can't use interrupts, poll on completion* \***********************************************/ uha_send_mbox(unit,mscp); +#ifdef UHADEBUG if(scsi_debug & TRACEINTERRUPTS) printf("cmd_wait "); +#endif /*UHADEBUG*/ do { if(uha_poll(unit,xs->timeout)) @@ -1094,12 +1120,9 @@ cheat = mscp; uha_free_mscp(unit,mscp,flags); } xs->error = XS_DRIVER_STUFFUP; - splx(s); return(HAD_ERROR); } } while (!(xs->flags & ITSDONE));/* something (?) else finished */ - splx(s); -scsi_debug = 0;uha_debug = 0; if(xs->error) { return(HAD_ERROR); @@ -1107,154 +1130,34 @@ scsi_debug = 0;uha_debug = 0; return(COMPLETE); } -/* - * +----------+ +----------+ +----------+ - * uha_soonest--->| later |--->| later|--->| later|--->0 - * | [Delta] | | [Delta] | | [Delta] | - * 0<---|sooner |<---|sooner |<---|sooner |<---uha_latest - * +----------+ +----------+ +----------+ - * - * uha_furtherest = sum(Delta[1..n]) - */ -uha_add_timeout(mscp,time) -struct mscp *mscp; -int time; + +uha_timeout(struct mscp *mscp) { - int timeprev; - struct mscp *prev; - int s = splbio(); - - if(prev = uha_latest) /* yes, an assign */ - { - timeprev = uha_furtherest; - } - else - { - timeprev = 0; - } - while(prev && (timeprev > time)) - { - timeprev -= prev->delta; - prev = prev->sooner; - } - if(prev) - { - mscp->delta = time - timeprev; - if( mscp->later = prev->later) /* yes an assign */ - { - mscp->later->sooner = mscp; - mscp->later->delta -= mscp->delta; - } - else - { - uha_furtherest = time; - uha_latest = mscp; - } - mscp->sooner = prev; - prev->later = mscp; - } - else - { - if( mscp->later = uha_soonest) /* yes, an assign*/ - { - mscp->later->sooner = mscp; - mscp->later->delta -= time; - } - else - { - uha_furtherest = time; - uha_latest = mscp; - } - mscp->delta = time; - mscp->sooner = (struct mscp *)0; - uha_soonest = mscp; - } - splx(s); -} - -uha_remove_timeout(mscp) -struct mscp *mscp; -{ - int s = splbio(); - - if(mscp->sooner) - { - mscp->sooner->later = mscp->later; - } - else - { - uha_soonest = mscp->later; - } - if(mscp->later) - { - mscp->later->sooner = mscp->sooner; - mscp->later->delta += mscp->delta; - } - else - { - uha_latest = mscp->sooner; - uha_furtherest -= mscp->delta; - } - mscp->sooner = mscp->later = (struct mscp *)0; - splx(s); -} - - -extern int hz; -#define ONETICK 500 /* milliseconds */ -#define SLEEPTIME ((hz * ONETICK) / 1000) -uha_timeout(arg) -int arg; -{ - struct mscp *mscp; int unit; int s = splbio(); - unsigned int stat; int port = uha_data[unit].baseport; - while( mscp = uha_soonest ) + unit = mscp->xs->adapter; + printf("uha%d:%d device timed out\n",unit + ,mscp->xs->targ); +#ifdef UHADEBUG + if(uha_debug & UHA_SHOWMSCPS) + uha_print_active_mscp(unit); +#endif /*UHADEBUG*/ + + if((uha_abort(unit,mscp) !=1) || (mscp->flags = MSCP_ABORTED)) { - if(mscp->delta <= ONETICK) - /***********************************************\ - * It has timed out, we need to do some work * - \***********************************************/ - { - unit = mscp->xs->adapter; - printf("uha%d:%d device timed out\n",unit - ,mscp->xs->targ); - if(uha_debug & UHA_SHOWMSCPS) - uha_print_active_mscp(); - - /***************************************\ - * Unlink it from the queue * - \***************************************/ - uha_remove_timeout(mscp); - - if((uha_abort(unit,mscp) !=1) || (mscp->flags = MSCP_ABORTED)) - { - printf("AGAIN"); - mscp->xs->retries = 0; /* I MEAN IT ! */ - uha_done(unit,mscp,FAIL); - } - else /* abort the operation that has timed out */ - { - printf("\n"); - uha_add_timeout(mscp,2000 + ONETICK); - mscp->flags = MSCP_ABORTED; - } - } - else - /***********************************************\ - * It has not timed out, adjust and leave * - \***********************************************/ - { - mscp->delta -= ONETICK; - uha_furtherest -= ONETICK; - break; - } + printf("AGAIN"); + mscp->xs->retries = 0; /* I MEAN IT ! */ + uha_done(unit,mscp,FAIL); + } + else /* abort the operation that has timed out */ + { + printf("\n"); + timeout(uha_timeout,mscp,2 * hz); + mscp->flags = MSCP_ABORTED; } splx(s); - timeout(uha_timeout,arg,SLEEPTIME); } uha_show_scsi_cmd(struct scsi_xfer *xs) @@ -1291,26 +1194,25 @@ struct mscp *mscp; ,mscp->opcode ,mscp->cdblen ,mscp->senselen); - printf(" sg:%d sgnum:%x datlen:%d hstat:%x tstat:%x delta:%d flags:%x\n" + printf(" sg:%d sgnum:%x datlen:%d hstat:%x tstat:%x flags:%x\n" ,mscp->sgth ,mscp->sg_num ,mscp->datalen ,mscp->ha_status ,mscp->targ_status - ,mscp->delta ,mscp->flags); uha_show_scsi_cmd(mscp->xs); } -uha_print_active_mscp() +uha_print_active_mscp(int unit) { - struct mscp *mscp; - mscp = uha_soonest; + struct mscp *mscp = uha_data[unit].mscps; + int i = NUHA; - while(mscp) + while(i--) { - uha_print_mscp(mscp); - mscp = mscp->later; + if(mscp->flags != MSCP_FREE) + uha_print_mscp(mscp); + mscp++; } - printf("Furtherest = %d\n",uha_furtherest); }