HEADS UP: PCI Chnages
Kevin Oberman
oberman at es.net
Mon Apr 12 09:48:54 PDT 2004
> 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
> @@ -246,48 +246,55 @@
> 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;
> }
>
> @@ -431,7 +429,7 @@
> 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
More information about the freebsd-current
mailing list