From owner-freebsd-drivers@FreeBSD.ORG Wed Nov 2 16:31:22 2011 Return-Path: Delivered-To: freebsd-drivers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 502FE1065670 for ; Wed, 2 Nov 2011 16:31:22 +0000 (UTC) (envelope-from sghctoma@gmail.com) Received: from mail-fx0-f54.google.com (mail-fx0-f54.google.com [209.85.161.54]) by mx1.freebsd.org (Postfix) with ESMTP id D81F58FC15 for ; Wed, 2 Nov 2011 16:31:21 +0000 (UTC) Received: by faar19 with SMTP id r19so903037faa.13 for ; Wed, 02 Nov 2011 09:31:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=date:from:to:subject:message-id:mime-version:content-type :content-disposition:user-agent; bh=RgIwHqOxpfvDV5d4svrlADXUDafy6ld93z0PYA70oSU=; b=CPpZVA2fojO1fxXO24ywJD82LhSwnvWMcLJ2pFSbX0QiZ1guxkl7ZIydU8lRTrZgb3 Vaa4x7ME7LXHhNzKqB4mVElxe/4S2B0/4p+ZpuX+2fLqX2NNPPtf7WPipmSid+v8Cp+8 Y1R4dXulbuU0L0pMPwOvWKojUCwplpzh331ho= Received: by 10.223.62.209 with SMTP id y17mr9365740fah.7.1320249708780; Wed, 02 Nov 2011 09:01:48 -0700 (PDT) Received: from localhost (mail.praudit.hu. [89.135.48.141]) by mx.google.com with ESMTPS id x19sm6202271fag.5.2011.11.02.09.01.45 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 02 Nov 2011 09:01:46 -0700 (PDT) Date: Wed, 2 Nov 2011 17:01:44 +0100 From: Tamas Szakaly To: freebsd-drivers@freebsd.org Message-ID: <20111102160144.GA487@izebigyomicsoda.praudit.hu> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Subject: ThinkPad battery charge control X-BeenThere: freebsd-drivers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Writing device drivers for FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Nov 2011 16:31:22 -0000 Hi, Two weaks ago a conversation started at freebsd-mobile about battery charge limiting. During this weekend I had some time to look up the ThinkPad 770 Technical Reference Manual (http://support.lenovo.com/en_US/detail.page?LegacyDocID=PFAN-3tuQQD), the ThinkPad Power Manager for Windows XP, and the tp_smapi Linux driver (http://sourceforge.net/projects/tpctl/files/tp_smap). I managed to write a kernel module that exposes the ThinkPad SMAPI features via the following sysctls: - hw.thinkpad_smapi.batX.start_threshold: charge start threshold (0-100) - hw.thinkpad_smapi.batX.stop_threshold: charge stop threshold (0-100) - hw.thinkpad_smapi.batX.force_discharge: enable/disable force discharge (0,1) - hw.thinkpad_smapi.batX.inhibit_charge_minutes: inhibit charge for given minutes (0-65535) X can be 0 or 1. The module works OK, but I have very-very little experience with kernel programming (added some sysctls to psm.c to control TrackPoint behaviour a year ago), and I have some concerns about how this functionality should be implemented correctly: - Is the sysctl way OK? Or should I expose those features via ioctl or character device read/write functions? - To access SMAPI, one have to write two I/O ports, 0xb2 and 0x4f. My problem is the following: the code works without mapping/allocating those two I/O ports, but I think, they should be mapped/allocated nevertheless. Am I right? - I used the term map/allocate, because I don't know what function to use to achieve this. At first I was using bus_space_map/bus_space_unmap like this: bus_space_map(X86_BUS_SPACE_IO, port, 1, 0, &bsh1) bus_space_map(X86_BUS_SPACE_IO, SMAPI_PORT, 1, 0, &bsh2) ... bus_space_unmap(X86_BUS_SPACE_IO, bsh1, 1) bus_space_unmap(X86_BUS_SPACE_IO, bsh2, 2) But neither of the drivers I saw use this pair of functions. Every one of them uses bus_alloc_resource/bus_release_resource. So I tried those functions as well: in identify: bus_set_resource(child, SYS_RES_IOPORT, 0, port, 1); bus_set_resource(child, SYS_RES_IOPORT, 1, SMAPI_PORT, 1); in probe: if (bus_get_resource_start(dev, SYS_RES_IOPORT, 0) == 0) return(ENXIO); if (bus_get_resource_start(dev, SYS_RES_IOPORT, 1) == 0) return(ENXIO); in attach: sc->rid1 = 0; sc->res1 = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->rid1, port, port, 1, RF_ACTIVE); sc->rid2 = 1; sc->res2 = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->rid2, SMAPI_PORT, SMAPI_PORT, 1, RF_ACTIVE); But the allocation fails. devinfo -r tells me, that I/O port 0xb2 is already allocated by acpi. So I tried to make acpi my driver's parent: DRIVER_MODULE(thinkpad_smapi, acpi, ... After this the allocation works, devinfo -r tells, that 0xb2 and 0x4f is allocted by my driver. But when I unload the module, and try to load it again, it fails. Please note, that bus_release_resource is called upon unloading the module and devinfo -r shows that 0xb2 is allocated by acpi again. What am I doing wrong? Sorry for the overly-long mail, and the possibly newbie questions, but I have read lots of man(9) pages, mailing list threads, and sources of drivers, and I am still confused. Any help is well appreciated. Thank you in advance! Regards, sghctoma --