From owner-freebsd-current@freebsd.org Mon Dec 10 20:57:08 2018 Return-Path: Delivered-To: freebsd-current@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7DB0213336AE for ; Mon, 10 Dec 2018 20:57:08 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from mail.baldwin.cx (bigwig.baldwin.cx [96.47.65.170]) (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 0E4236E7F8; Mon, 10 Dec 2018 20:57:08 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from John-Baldwins-MacBook-Pro-2.local (ralph.baldwin.cx [66.234.199.215]) by mail.baldwin.cx (Postfix) with ESMTPSA id 2B22010B783; Mon, 10 Dec 2018 15:57:06 -0500 (EST) Subject: Re: Composite PCI devices in FreeBSD (mfd in Linux) To: Ian Lepore , Anthony Jenkins , FreeBSD CURRENT References: <1544473194.1860.340.camel@freebsd.org> Cc: Gleb Popov <6yearold@gmail.com> From: John Baldwin Openpgp: preference=signencrypt Autocrypt: addr=jhb@FreeBSD.org; keydata= xsDiBETQ+XcRBADMFybiq69u+fJRy/0wzqTNS8jFfWaBTs5/OfcV7wWezVmf9sgwn8TW0Dk0 c9MBl0pz+H01dA2ZSGZ5fXlmFIsee1WEzqeJzpiwd/pejPgSzXB9ijbLHZ2/E0jhGBcVy5Yo /Tw5+U/+laeYKu2xb0XPvM0zMNls1ah5OnP9a6Ql6wCgupaoMySb7DXm2LHD1Z9jTsHcAQMD /1jzh2BoHriy/Q2s4KzzjVp/mQO5DSm2z14BvbQRcXU48oAosHA1u3Wrov6LfPY+0U1tG47X 1BGfnQH+rNAaH0livoSBQ0IPI/8WfIW7ub4qV6HYwWKVqkDkqwcpmGNDbz3gfaDht6nsie5Z pcuCcul4M9CW7Md6zzyvktjnbz61BADGDCopfZC4of0Z3Ka0u8Wik6UJOuqShBt1WcFS8ya1 oB4rc4tXfSHyMF63aPUBMxHR5DXeH+EO2edoSwViDMqWk1jTnYza51rbGY+pebLQOVOxAY7k do5Ordl3wklBPMVEPWoZ61SdbcjhHVwaC5zfiskcxj5wwXd2E9qYlBqRg80eSm9obiBCYWxk d2luIDxqb2huQGJhbGR3aW4uY3g+wmMEExECACMCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIX gAUCRND5wwIZAQAKCRBy3lIGd+N/BNLXAJ9KIb6teuDL1W+FkCgvv+y8PxKTkACeIUfbn3sl cueBzqTcf09idwa8YTbOwU0ERND5ghAIAPwsO0B7BL+bz8sLlLoQktGxXwXQfS5cInvL17Ds gnr31AKa94j9EnXQyPEj7u0d+LmEe6CGEGDh1OcGFTMVrof2ZzkSy4+FkZwMKJpTiqeaShMh +GojXlwIMDxyADYvBIg3eN5YdFKaPQpfgSqhT+7El7w+wSZZD8pPQuLAnie5iz9C8iKy4/cM SOrHYUK/tO+Nhw8Jjlw94Ik0T80iEhI2t+XBVjwdfjbq3HrJ0ehqdBwukyeJRYKmbn298KOF QVHOEVbHA4rF/37jzaMadK43FgJ0SAhPPF5l4l89z5oPu0b/+5e2inA3b8J3iGZxywjM+Csq 1tqzhltEc7Q+E08AAwUIAL+15XH8bPbjNJdVyg2CMl10JNW2wWg2Q6qdljeaRqeR6zFus7EZ TwtXsNzs5bP8y51PSUDJbeiy2RNCNKWFMndM22TZnk3GNG45nQd4OwYK0RZVrikalmJY5Q6m 7Z164yrZgIXFdKj2t8F+x613/SJW1lIr9/bDp4U9tw0V1g3l2dFtD3p3ZrQ3hpoDtoK70ioI AjjHaIXIAcm3FGZFXy503DOA0KaTWwvOVdYCFLm3zWuSOmrX/GsEc7ovasOWwjPn878qVjbU KWwxQ4QkF4OhUV9zPtf9tDSAZ3x7QSwoKbCoRCZ/xbyTUPyQ1VvNy/mYrBcYlzHodsaqUDjH uW/CSQQYEQIACQUCRND5ggIbDAAKCRBy3lIGd+N/BCO8AJ9j1dWVQWxw/YdTbEyrRKOY8YZN wwCfafMAg8QvmOWnHx3wl8WslCaXaE8= Message-ID: <05b1183c-6117-267b-42f9-19e750adfa07@FreeBSD.org> Date: Mon, 10 Dec 2018 12:57:04 -0800 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: <1544473194.1860.340.camel@freebsd.org> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.4.3 (mail.baldwin.cx); Mon, 10 Dec 2018 15:57:06 -0500 (EST) X-Virus-Scanned: clamav-milter 0.99.2 at mail.baldwin.cx X-Virus-Status: Clean X-Rspamd-Queue-Id: 0E4236E7F8 X-Spamd-Result: default: False [-2.98 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_SHORT(-0.98)[-0.983,0]; ASN(0.00)[asn:11403, ipnet:96.47.64.0/20, country:US]; NEURAL_HAM_MEDIUM(-1.00)[-1.000,0]; NEURAL_HAM_LONG(-1.00)[-1.000,0] X-Rspamd-Server: mx1.freebsd.org X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Dec 2018 20:57:08 -0000 On 12/10/18 12:19 PM, Ian Lepore wrote: > On Mon, 2018-12-10 at 14:42 -0500, Anthony Jenkins wrote: >> On 12/10/18 1:26 PM, John Baldwin wrote: >>> >>> On 12/10/18 9:00 AM, Anthony Jenkins wrote: >>>> >>>> Hi all, >>>> >>>> I'm trying to port an Intel PCI I2C controller from Linux to >>>> FreeBSD. >>>> Linux represents this device as an MFD (multi-function device), >>>> meaning >>>> it has these "sub-devices" that can be handed off to other >>>> drivers to >>>> actually attach devices to the system.  The Linux "super" PCI >>>> device is >>>> the intel-lpss-pci.c, and the "sub" device is i2c-designware- >>>> platdrv.c, >>>> which represents the DesignWare driver's "platform" attachment to >>>> the >>>> Linux system.  FreeBSD also has a DesignWare I2C controller >>>> driver, >>>> ig4(4), but it only has PCI and ACPI bus attachment >>>> implementations. >>>> >>>> I have a port of the Linux intel-lpss driver to FreeBSD, but now >>>> I'm >>>> trying to figure out the best way to give FreeBSD's ig4(4) driver >>>> access >>>> to my lpss(4) device.  I'm thinking I could add an ig4_lpss.c >>>> describing >>>> the "attachment" of an ig4(4) to an lpss(4).  Its probe() method >>>> would >>>> scan the "lpss" devclass for devices, and its attach() method >>>> would >>>> attach itself as a child to the lpss device and "grab" the >>>> portion of >>>> PCI memory and the IRQ that the lpss PCI device got. >>>> >>>> Is this the "FreeBSD Way (TM)" of handling this type of device?  >>>> If not, >>>> can you recommend an existing FreeBSD driver I can model my code >>>> after? >>>> If my approach is acceptable, how do I fully describe the ig4(4) >>>> device's attachment to the system?  Is simply making it a child >>>> of >>>> lpss(4) sufficient?  It's "kind of" a PCI device (it is >>>> controlled via >>>> access to a PCI memory region and an IRQ), but it's a sub-device >>>> of an >>>> actual PCI device (lpss(4)) attached to PCI. >>>> How would my ig4_lpss attachment get information from the lpss(4) >>>> driver >>>> about what it probed? >>> There are some existing PCI drivers that act as "virtual" busses >>> that attach >>> child devices.  For example, vga_pci.c can have drm, agp, and >>> acpi_video >>> child devices.  There are also some SMBus drivers that are also >>> PCI-ISA >>> bridges and thus create separate child devices. >> Yeah I was hoping to avoid using video PCI devices as a model, as  >> complex as they've gotten recently.  I'll check out its bus glue >> logic. >> >>> >>> For a virtual bus like this, you need to figure out how your child >>> devices >>> will be enumerated.  A simple way is to let child devices use an >>> identify >>> routine that looks at each parent device and decides if a child >>> device >>> for that driver makes sense.  It can then add a child device in the >>> identify routine. >> Really an lpss parent PCI parent device can only have the following: >> >>   * one of {I2C, UART, SPI} controller >>   * optionally an IDMA64 controller >> >> so I was thinking a child ig4(4) device would attach to lpss iff >> >>   * the lpss device detected an I2C controller >>   * no other ig4 device is already attached >> >> I haven't fiddled with identify() yet, will look at that tonight. >> > > If this is just another "bus" an ig4 instance can attach to, I'd think > the recipe would be to add another DRIVER_MODULE() to ig4_iic.c naming > ig4_lpss as the parent. Then add a new ig4_lpss.c modeled after the > existing pci and acpi attachment code, its DRIVER_MODULE() would name > lpss as parent, and its probe routine would return BUS_PROBE_NOWILDCARD > (attach only if specifically added by the parent). > > Then there would be a new lpss driver that does the resource managment > stuff mentioned above, and if it detects configuration for I2C it would > do a device_add_child(lpssdev, "ig4_lpss", -1) followed by > bus_generic_attach(). There'd be no need for identify() in the child in > that case, I think. > > But take jhb's word over mine on any of this stuff, he's been around > since the days when these mechanisms were all invented, whereas I tend > to cut and paste that bus and driver attachment stuff in semi-ignorance > when I'm working on drivers. Doing the device_add_child in the parent driver's attach routine is also fine instead of using an identify routine. It's mostly a matter of which driver should be in charge of adding the child device (e.g. would you want lpss self-contained or should the parent driver know about it explicitly). If you have an existing ig4 driver you are going to reuse, then you will need to ensure you fake up the resource stuff so that the existing code works perhaps, though that depends on where the bus_alloc_resource calls occur. If they are in shared code you have to fake more. If they are in the bus-specific attach routines, then you can just put lpss specific logic in the lpss-specific attach routine. >>> To handle things like resources, you want to have >>> bus_*_resource methods that let your child device use the normal >>> bus_* >>> functions to allocate resources.  At the simplest end you don't >>> need to >>> permit any sharing of BARs among multiple children so you can just >>> proxy >>> the requests in the "real" PCI driver.  (vga_pci.c does this)  If >>> you need >>> the BARs to be shared you have a couple of options such as just >>> using a >>> refcount on the BAR resource but letting multiple devices allocate >>> the same >>> BAR.  If you want to enforce exclusivity (once a device allocates >>> part of >>> a BAR then other children shouldn't be permitted to do so), then >>> you will >>> need a more complicated solution. >> Another homework assignment for me - bus_*_resource methods. >> >> There are 2 or 3 mutually-exclusive sub-regions in the single memory >> BAR: >> >>   * 0x000 - 0x200 : I2C sub-device registers >>   * 0x200 - 0x300 : lpss and I2C sub-device registers >>   * 0x800 - 0x1000 : IDMA sub-device registers (optional) Hmm, so with this arrangement, you could either "cheat" and let all the children just use the same BAR, or you could get fancy and create a separate rman and sub-allocate resources from that for the different ranges that you assign to each child. -- John Baldwin