From owner-freebsd-bugs Fri Apr 17 21:50:02 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id VAA28890 for freebsd-bugs-outgoing; Fri, 17 Apr 1998 21:50:02 -0700 (PDT) (envelope-from owner-freebsd-bugs@FreeBSD.ORG) Received: (from gnats@localhost) by hub.freebsd.org (8.8.8/8.8.8) id VAA28871; Fri, 17 Apr 1998 21:50:01 -0700 (PDT) (envelope-from gnats) Date: Fri, 17 Apr 1998 21:50:01 -0700 (PDT) Message-Id: <199804180450.VAA28871@hub.freebsd.org> To: freebsd-bugs Cc: From: Ian West Subject: Re: kern/6252: ide cdrom hangs system when on same bus as ide zip drive Reply-To: Ian West Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org The following reply was made to PR kern/6252; it has been noted by GNATS. From: Ian West To: freebsd-gnats-submit@freebsd.org Cc: Subject: Re: kern/6252: ide cdrom hangs system when on same bus as ide zip drive Date: Sat, 18 Apr 1998 14:13:37 +0930 (CST) I have isolated this problem, and have fixed it on my machine. It is due to only a single state variable being kept for the ide channel to determine the ability of the drive to do an interupt during the command phase of a transaction (intrcmd). If one of your devices can, and the other cannot, then the one that cannot will always hang the system when accessed. My solution to this, which may well not be the best one :-) is to keep an array of two variables, one for each drive. This has been running flawlessly for a week or so now, and may be of some use. The following patches are applied against 3.0 current, but as far as I can see, should work anywhere with a few changes. They are pretty simple. atapi.h and atapi.c need to be changed very slightly. ====================================================================== *** atapi.h Sun Mar 1 18:57:29 1998 --- /root/atapi.h Sat Apr 11 11:24:07 1998 *************** *** 241,249 **** struct atapi { /* ATAPI controller data */ u_short port; /* i/o port base */ u_char ctrlr; /* physical controller number */ u_char debug : 1; /* trace enable flag */ u_char cmd16 : 1; /* 16-byte command flag */ - u_char intrcmd : 1; /* interrupt before cmd flag */ u_char slow : 1; /* slow reaction device */ u_char use_dsc : 1; /* use DSC completition handeling */ u_char wait_for_dsc : 1; --- 241,249 ---- struct atapi { /* ATAPI controller data */ u_short port; /* i/o port base */ u_char ctrlr; /* physical controller number */ + u_char intrcmd[2]; /* interrupt before cmd flag */ u_char debug : 1; /* trace enable flag */ u_char cmd16 : 1; /* 16-byte command flag */ u_char slow : 1; /* slow reaction device */ u_char use_dsc : 1; /* use DSC completition handeling */ u_char wait_for_dsc : 1; ====================================================================== *** atapi.c Sun Mar 1 18:57:27 1998 --- /root/atapi.c Sat Apr 11 11:24:07 1998 *************** *** 218,229 **** /* DRQ type */ switch (ap->drqtype) { case AT_DRQT_MPROC: ata->slow = 1; break; ! case AT_DRQT_INTR: printf (", intr"); ata->intrcmd = 1; break; case AT_DRQT_ACCEL: printf (", accel"); break; default: printf (", drq%d", ap->drqtype); } if (ata->slow) ! ata->intrcmd = 0; /* overlap operation supported */ if (ap->ovlapflag) --- 218,229 ---- /* DRQ type */ switch (ap->drqtype) { case AT_DRQT_MPROC: ata->slow = 1; break; ! case AT_DRQT_INTR: printf (", intr"); ata->intrcmd[unit] = 1; break; case AT_DRQT_ACCEL: printf (", accel"); break; default: printf (", drq%d", ap->drqtype); } if (ata->slow) ! ata->intrcmd[unit] = 0; /* overlap operation supported */ if (ap->ovlapflag) *************** *** 575,582 **** atapi_done (ata); goto again; } ! ! if (ata->intrcmd) /* Wait for interrupt before sending packet command */ return (1); --- 575,581 ---- atapi_done (ata); goto again; } ! if (ata->intrcmd[ac->unit]) /* Wait for interrupt before sending packet command */ return (1); *************** *** 632,638 **** int atapi_wait_cmd (struct atapi *ata, struct atapicmd *ac) { /* Wait for DRQ from 50 usec to 3 msec for slow devices */ ! int cnt = ata->intrcmd ? 10000 : ata->slow ? 3000 : 50; int ireason = 0, phase = 0; /* Wait for command phase. */ --- 631,637 ---- int atapi_wait_cmd (struct atapi *ata, struct atapicmd *ac) { /* Wait for DRQ from 50 usec to 3 msec for slow devices */ ! int cnt = ata->intrcmd[ac->unit] ? 10000 : ata->slow ? 3000 : 50; int ireason = 0, phase = 0; /* Wait for command phase. */ ====================================================================== To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message