Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Apr 1998 21:50:01 -0700 (PDT)
From:      Ian West <ian@damocles.apdata.com.au>
To:        freebsd-bugs
Subject:   Re: kern/6252: ide cdrom hangs system when on same bus as ide zip drive
Message-ID:  <199804180450.VAA28871@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/6252; it has been noted by GNATS.

From: Ian West <ian@damocles.apdata.com.au>
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199804180450.VAA28871>