From owner-freebsd-hackers@freebsd.org Thu Sep 10 22:33:00 2015 Return-Path: Delivered-To: freebsd-hackers@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9A21CA01820 for ; Thu, 10 Sep 2015 22:33:00 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from bigwig.baldwin.cx (bigwig.baldwin.cx [IPv6:2001:470:1f11:75::1]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 73C781A99 for ; Thu, 10 Sep 2015 22:33:00 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from ralph.baldwin.cx (c-73-231-226-104.hsd1.ca.comcast.net [73.231.226.104]) by bigwig.baldwin.cx (Postfix) with ESMTPSA id C179AB939; Thu, 10 Sep 2015 18:32:58 -0400 (EDT) From: John Baldwin To: freebsd-hackers@freebsd.org Cc: "Pokala, Ravi" Subject: Re: bus_.*_resource() and rid Date: Thu, 10 Sep 2015 14:24:20 -0700 Message-ID: <1685918.WyYIclYTSg@ralph.baldwin.cx> User-Agent: KMail/4.14.3 (FreeBSD/10.2-PRERELEASE; KDE/4.14.3; amd64; ; ) In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.2.7 (bigwig.baldwin.cx); Thu, 10 Sep 2015 18:32:58 -0400 (EDT) X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 10 Sep 2015 22:33:00 -0000 On Wednesday, September 09, 2015 02:37:04 AM Pokala, Ravi wrote: > Hi folks, > > I'm modifying a home-grown device driver; this is the first time I've > played around in device-probe and -attach, so I'm a bit out of my element > here. This is an LPC device attached to a PCI-ISA bridge (aka the LPC > controller). It's accessed through IOPORT, and the BIOS sets up enough > stuff that we can look for it. > > One thing that's confusing me is the "rid" which is passed to a bunch of > the bus_.*_resource() functions. I've looked at bus_set_resource(9), > bus_alloc_resource(9), and section 10.5 of the Architecture Handbook[1], > and I'm still confused. > > bus_alloc_resource(9) says: > > rid points to a bus specific handle that identifies the resource being > allocated. For ISA this is an index into an array of resources that > have > been setup for this device by either the PnP mechanism, or via the > hints > mechanism. ... > > > But there's no indication as to how we get that index. One possibility is > that the value passed in doesn't matter; bus_alloc_resource() sets it > correctly and the caller can use the new value. However, that doesn't > appear to be the case, since lots of times rid is ignored after the call > to bus_alloc_resource(). > > For the sake of discussion, here are stripped-down versions of our probe > and attach functions: > > xxx_probe_unit(device_t dev) > { > uint32_t ioport_base; > uint32_t ioport_size; > int rc; > > /* Device identification stuff; details unimportant, but we determine > * ioport_base and ioport_size. > */ > > rc = bus_set_resource( > /* dev */ dev, > /* type */ SYS_RES_IOPORT, > /* rid */ 0, > /* start */ ioport_base, > /* count */ ioport_size); > } > > Most of those args are obvious, but I have no idea why rid is 0. It looks > like lots of drivers pass in a rid of 0, and the original author might > have just shrugged and gone with "convention". > > xxx_attach_unit(device_t dev) > { > struct xxx_softc *sc; > int rid; > struct resource res; > > sc = device_get_softc(dev); > > /* Device configuration stuff; details unimportant. */ > > rid = 0; > res = bus_alloc_resource( > /* dev */ dev, > /* type */ SYS_RES_IOPORT, > /* rid */ &rid, > /* start */ 0, > /* end */ ~0, > /* count */ sc->ioport_size, > /* flags */ RF_ACTIVE); > > /* save stuff for use with bus_space_{read,write}_1() */ > sc->iobase_addr = rman_get_start(res); > sc->iobase_bustag = rman_get_bustag(res); > sc->iobase_bushandle = rman_get_bushandle(res); > sc->dev = dev; > } > > Again, most things are fairly obvious, but I have no idea why rid is 0. > It's passed by reference to bus_alloc_resource(), but the > potentially-altered value is never stored or used. > > The lazy part of me says to just go with blindly passing in 0, because it > works. However, the new device I'm adding support for will have multiple > IOPORT ranges associated with it, so I'm not sure if passing 0 is the > right thing. > > Any help would be appreciated. Each bus decides how to manage RIDs. For PCI devices, RIDs are the address of the corresponding BAR for memory and I/O port resources and follow a different convention for interrupts (0 == INTx, 1...N == MSI/MSI-X). For ISA devices (and ACPI) RIDs are 0...N. If a device is enumerated via the firmware (e.g. ACPI DSDT entry with _CRS or PNPBIOS data for non-ACPI) then the firmware assigned resources are set for you by the parent bus and start at 0 (if you have two I/O port resources you'd have the second one at rid 1). If you are doing this on the LPC, then that it is actually a PCI device, and I don't know if the PCI bus is really going to let you create a rid at 0 via bus_set_resource(). Hmm, it should, but it's kind of a bit hacky. It might be somewhat cleaner if instead you treat this as an ISA device that is a child of isa0 below the LPC device. You can use an identify routine that looks at the grandparent isab0 device and then allocates this. However, a rid of 0 "should" work. You can check the resource list of the device in kgdb to see if there's a valid resource entry for rid 0. You could also try calling bus_get_resource() in your attach routine to see if the bus_set_resource() "worked". -- John Baldwin