Subject: Re: kern/22869: Slave IDE drive not detected
To: Charles M. Hannum <abuse@spamalicious.com>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: tech-kern
Date: 09/23/2003 11:54:00
On Tue, Sep 23, 2003 at 07:42:27AM +0000, Charles M. Hannum wrote:
> 
> > Also, for your CF card, you may be hitting the problem handled by
> > WDC_CAPABILITY_NO_EXTRA_RESETS.
> 
> I'm not at all convinced that "quirk" is actually necessary.  Among
> other things, there was a missing delay() before it started polling
> the status register in wdcreset().

Cool

> 
> I've reworked this a little to not try to do an extra IDENTIFY
> command.  The following patch mostly alleviates the problem on my
> laptop, and makes CF card insertion reasonably fast.
> 
> Unless someone can provide negative test results for this, I'm going
> to commit it in the next 2 days.
> 
> 
>  		if (ret_value == 0)
> @@ -312,16 +296,13 @@
>  	/* assert SRST, wait for reset to complete */
>  	bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
>  	    WDSD_IBM);
> -	delay(10);
> +	delay(10);	/* 400ns delay */
>  	bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
> -	    WDCTL_RST | WDCTL_IDS); 
> -	DELAY(1000);
> -	bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
> -	    WDCTL_IDS);
> -	delay(1000);
> +	    WDCTL_RST | WDCTL_IDS | WDCTL_4BIT); 
> +	delay(2000);

Are you sure we need WDCTL_4BIT here ?
I fear this may break pre-ATA drives.

>  				    chp->wdc->sc_dev.dv_xname,
> @@ -855,15 +832,13 @@
>  		chp->wdc->select(chp,0);
>  	bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
>  	    WDSD_IBM); /* master */
> -	bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
> -	    WDCTL_RST | WDCTL_IDS);
> -	delay(1000);
> +	delay(10);	/* 400ns delay */
>  	bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
> -	    WDCTL_IDS);
> -	delay(1000);
> +	    WDCTL_RST | WDCTL_IDS | WDCTL_4BIT);
> +	delay(2000);

Same here

> @@ -886,7 +861,7 @@
>  	int drv_mask;
>  {
>  	int timeout;
> -	u_int8_t st0, st1;
> +	u_int8_t st0, er0, st1, er1;
>  #ifdef WDCDEBUG
>  	u_int8_t sc0, sn0, cl0, ch0;
>  	u_int8_t sc1, sn1, cl1, ch1;
> @@ -899,6 +874,7 @@
>  		    WDSD_IBM); /* master */
>  		delay(10);
>  		st0 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
> +		er0 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_error);
>  #ifdef WDCDEBUG
>  		sc0 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt);
>  		sn0 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_sector);
> @@ -911,6 +887,7 @@
>  		    WDSD_IBM | 0x10); /* slave */
>  		delay(10);
>  		st1 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
> +		er1 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_error);
>  #ifdef WDCDEBUG
>  		sc1 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt);
>  		sn1 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_sector);
> @@ -944,6 +921,10 @@
>  	if (st1 & WDCS_BSY)
>  		drv_mask &= ~0x02;
>  end:
> +	if (er0 != 0x01 && er0 != 0x81)
> +		drv_mask &= ~0x01;
> +	if (er1 != 0x01)
> +		drv_mask &= ~0x02;

I don't think the above changes are needed to solve your problem; could
you try without them, and remove them if not needed ?

I'll try to check with an old drive later today.

--
Manuel Bouyer, LIP6, Universite Paris VI.           Manuel.Bouyer@lip6.fr
     NetBSD: 24 ans d'experience feront toujours la difference
--