Re: HEADS UP: PCI Chnages

From: Kevin Oberman <oberman_at_es.net>
Date: Mon, 12 Apr 2004 09:48:52 -0700
> Date: Sun, 11 Apr 2004 23:19:27 -0600 (MDT)
> From: "M. Warner Losh" <imp_at_bsdimp.com>
> 
> In message: <446170000.1081743884_at_lerlaptop.lerctr.org>
>             Larry Rosenman <ler_at_lerctr.org> writes:
> : 
> : 
> : --On Sunday, April 11, 2004 21:05:24 -0700 Kevin Oberman <oberman_at_es.net> 
> : wrote:
> : 
> : >> Date: Sun, 11 Apr 2004 18:34:55 -0600 (MDT)
> : >> From: "M. Warner Losh" <imp_at_bsdimp.com>
> : >>
> : >> Try this patch
> : >
> : > Bingo! I am running with the new kernel as I type this.
> : as soon as OOo-1.1.1 finishes building, I'll try the new kernel waiting
> : in the wings on this box (probably in the AM at this point), but this is a 
> : good sign :)
> 
> You might also try
> 	http://people.freebsd.org/~imp/ata-patch
> 
> This patch is also discected here, to make sure I have my analysis
> right.
> 
> Index: ata-pci.c
> ===================================================================
> RCS file: /cache/ncvs/src/sys/dev/ata/ata-pci.c,v
> retrieving revision 1.77
> diff -u -r1.77 ata-pci.c
> --- ata-pci.c	17 Mar 2004 17:50:27 -0000	1.77
> +++ ata-pci.c	12 Apr 2004 04:54:18 -0000
> _at__at_ -246,48 +246,55 _at__at_
>      if (type == SYS_RES_IOPORT) {
>  	switch (*rid) {
>  	case ATA_IOADDR_RID:
> +	    /*
> +	     * ATA master devices are hard wired to the traditional ata
> +	     * I/O addresses.  Some devices have these resources wired to
> +	     * their BARs, while others do not, hence the need to hardwire
> +	     */
>  	    if (ATA_MASTERDEV(dev)) {
> -		myrid = 0;
>  		start = (unit ? ATA_SECONDARY : ATA_PRIMARY);
>  		end = start + ATA_IOSIZE - 1;
>  		count = ATA_IOSIZE;
> -		res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
> -					 SYS_RES_IOPORT, &myrid,
> -					 start, end, count, flags);
> -	    }
> -	    else {
> -		myrid = 0x10 + 8 * unit;
> -		res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
> -					 SYS_RES_IOPORT, &myrid,
> -					 start, end, count, flags);
>  	    }
> +	    myrid = 0x10 + 8 * unit;
> +	    res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
> +				     SYS_RES_IOPORT, &myrid,
> +				     start, end, count, flags);
>  	    break;
>  
> 
> OK.  What I'm doing above is changing how we do the allocation a
> little.  Before, one had to play 'tricks' to get the resources
> allocated correctly.  There was code in the pci bus that prevented
> most allocations like this from succeeding, as well as other
> complications.
> 
> This simplifies these past workarounds now that the PCI bus allocation
> has been tightened up.  The old ata code would work with the those
> devices that did NOT have the resources encoded in the BARs.  This is
> because the new PCI code reserves BAR resources for the exclusive use
> of that device.
> 
> 
> 
>  	case ATA_ALTADDR_RID:
>  	    if (ATA_MASTERDEV(dev)) {
> -		myrid = 0;
> +#if 0
>  		start = (unit ? ATA_SECONDARY : ATA_PRIMARY) + ATA_ALTOFFSET;
>  		end = start + ATA_ALTIOSIZE - 1;
>  		count = ATA_ALTIOSIZE;
> -		res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
> -					 SYS_RES_IOPORT, &myrid,
> -					 start, end, count, flags);
> +#else
> +		start = (unit ? ATA_SECONDARY : ATA_PRIMARY) + ATA_ALTOFFSET - 2;
> +		count = 4;
> +		end = start + count - 1;
> +#endif
>  	    }
> -	    else {
> -		myrid = 0x14 + 8 * unit;
> +printf("ata altaddr start %#lx end %#lx count %#lx\n", start, end, count);
> +	    myrid = 0x14 + 8 * unit;
> +	    res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
> +	                             SYS_RES_IOPORT, &myrid,
> +				     start, end, count, flags);
> +
> +	    /*
> +	     * I don't understand why we need to do this dance.  If we get
> +	     * the resource, then we release it and allocated something
> +	     * else.  This makes little sense to me, and might, in fact
> +	     * be a bug.
> +	     */
> +	    if (res && !ATA_MASTERDEV(dev)) {
> +		start = rman_get_start(res) + 2;
> +		end = start + ATA_ALTIOSIZE - 1;
> +		count = ATA_ALTIOSIZE;
> +		BUS_RELEASE_RESOURCE(device_get_parent(dev), dev,
> +		                     SYS_RES_IOPORT, myrid, res);
>  		res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
>  					 SYS_RES_IOPORT, &myrid,
>  					 start, end, count, flags);
> -		if (res) {
> -			start = rman_get_start(res) + 2;
> -			end = start + ATA_ALTIOSIZE - 1;
> -			count = ATA_ALTIOSIZE;
> -			BUS_RELEASE_RESOURCE(device_get_parent(dev), dev,
> -					     SYS_RES_IOPORT, myrid, res);
> -			res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
> -						 SYS_RES_IOPORT, &myrid,
> -						 start, end, count, flags);
> -		}
>  	    }
>  	    break;
>  	}
> 
> _at__at_ -431,7 +429,7 _at__at_
>  	ch->r_io[i].offset = i;
>      }
>      ch->r_io[ATA_ALTSTAT].res = altio;
> -    ch->r_io[ATA_ALTSTAT].offset = 0;
> +    ch->r_io[ATA_ALTSTAT].offset = 2;
>      ch->r_io[ATA_IDX_ADDR].res = io;
>  
>      if (ctlr->r_res1) {
> 
> These are more complicated.  We want to allocate 0x376 and 0x3f6 (Each
> for a length of 1).  However, there's a problem with that.  The
> problem is that this resource isn't encodable in a PCI bar.  BARs must
> be at least 4 in size, and aligned to the size of the resource.  So
> the above code tries to round correctly to copensate.  I'm not sure
> that I'm entirely happy with it, but it works for me.
> 
> Warner

Works fine here, too.

atapci0: <Intel ICH3 UDMA100 controller> port 0x1860-0x186f,0x374-0x377,0x170-0x177,0x3f4-0x3f7,0x1f0-0x1f7 at device 31.1 on pci0
atapci0: Bus reserved 0x10 bytes for rid 0x20 type 4 at 0x1860
atapci0: Bus reserved 0x8 bytes for rid 0x10 type 4 at 0x1f0
ata altaddr start 0x3f4 end 0x3f7 count 0x4
atapci0: Bus reserved 0x4 bytes for rid 0x14 type 4 at 0x3f4
ata0: reset tp1 mask=03 ostat0=50 ostat1=00
ata0-master: stat=0x50 err=0x01 lsb=0x00 msb=0x00
ata0-slave:  stat=0x00 err=0x01 lsb=0x00 msb=0x00
ata0: reset tp2 mask=03 stat0=50 stat1=00 devices=0x1<ATA_MASTER>
ata0: at 0x1f0 irq 14 on atapci0
ata0: [MPSAFE]
atapci0: Bus reserved 0x8 bytes for rid 0x18 type 4 at 0x170
ata altaddr start 0x374 end 0x377 count 0x4
atapci0: Bus reserved 0x4 bytes for rid 0x1c type 4 at 0x374
ata1: reset tp1 mask=03 ostat0=50 ostat1=00
ata1-master: stat=0x00 err=0x01 lsb=0x14 msb=0xeb
ata1-slave:  stat=0x00 err=0x00 lsb=0x00 msb=0x00
ata1: reset tp2 mask=03 stat0=00 stat1=00 devices=0x4<ATAPI_MASTER>
ata1: at 0x170 irq 15 on atapci0
ata1: [MPSAFE]

Clearly a little odd, but it works for me, too. 

While you were at it, you fixed my Xircom RBEM56G-100 modem. As I mentioned
in a response on mobile this morning, it stopped working last fall. It
was still not working as of Tuesday, April 6. After your patches of 4/9
and this fix, I suddenly am allocating the IRQ again. Cool! (I have not
been about to plug in to a real phone line, so it may not really be
working, but /dev/cuaa0 responds to AT commands as expected including
"NO DIALTONE".)

So this is double thanks!
-- 
R. Kevin Oberman, Network Engineer
Energy Sciences Network (ESnet)
Ernest O. Lawrence Berkeley National Laboratory (Berkeley Lab)
E-mail: oberman_at_es.net			Phone: +1 510 486-8634
Received on Mon Apr 12 2004 - 07:48:54 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:50 UTC