From owner-freebsd-hackers@FreeBSD.ORG Mon Aug 7 21:21:46 2006 Return-Path: X-Original-To: freebsd-hackers@freebsd.org Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7868916A4DD for ; Mon, 7 Aug 2006 21:21:46 +0000 (UTC) (envelope-from nike_d@cytexbg.com) Received: from office.suresupport.com (office.suresupport.com [213.145.98.15]) by mx1.FreeBSD.org (Postfix) with SMTP id 32D6B43D46 for ; Mon, 7 Aug 2006 21:21:44 +0000 (GMT) (envelope-from nike_d@cytexbg.com) Received: (qmail 64892 invoked by uid 1026); 7 Aug 2006 21:23:39 -0000 Received: from 213.145.98.14 by office.suresupport.com (envelope-from , uid 1004) with qmail-scanner-1.23 (f-prot: 4.4.2/3.14.11. Clear:RC:1(213.145.98.14):. Processed in 0.169765 secs); 07 Aug 2006 21:23:39 -0000 Received: from unknown (HELO ndenev.office.suresupport.com) (213.145.98.14) by office.suresupport.com with SMTP; 7 Aug 2006 21:23:39 -0000 From: Niki Denev To: John Baldwin Date: Tue, 8 Aug 2006 00:18:29 +0300 User-Agent: KMail/1.9.3 References: <44D4A5DC.7080403@cytexbg.com> <200608071527.50711.jhb@freebsd.org> In-Reply-To: <200608071527.50711.jhb@freebsd.org> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200608080018.29945.nike_d@cytexbg.com> Cc: freebsd-hackers@freebsd.org Subject: Re: jkh weird problem (reading pci device memory) X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 07 Aug 2006 21:21:46 -0000 On Monday 07 August 2006 22:27, John Baldwin wrote: > On Saturday 05 August 2006 10:06, Niki Denev wrote: > > for(i=0; i < sizeof(config_table_t); i++) { > > r = bus_space_read_1(sc->bar.tag, sc->bar.hdl, i); > > *((u_int8_t *)&sc->cfg_table + i) = r; > > } > > Note that you can replace this with: > > bus_space_read_multi_1(sc->bar.tag, sc->bar.hdl, 0, > (u_int8_t *)&sc->cfg_table, sizeof(config_table_t)); > I tried this, but for some reason it gave me different result than the loop i'm using right now. maybe i'm not doing something right, i'll check again. > However, if you are really reading in a table with more than just chars, > you might want to read the individual fields and byteswap them as needed > (if you care about portability to a big-endian arch like sparc). That is, > if your device stores the table as little-endian and you had: > > typedef struct _config_table { > uint32_t signature; > uint16_t version; > uint8_t dummy; > } config_table_t; > > You would do this instead: > > sc->cfg_table.signature = letoh32(bus_read_4(sc->bar.res, 0)); > sc->cfg_table.version = letoh16(bus_read_2(sc->bar.res, 4)); > sc->cfg_table.dummy = bus_read_1(sc->bar.res, 5); Yes, i'm aware of this problem, and if everything goes well i will try to make it big-endian friendly, but for now it's easier for me to deal with less code :) > > (Note this also uses the shorter bus_read functions which just take a > struct resouce *.) > Cool! this looks much more convenient. Maybe they must be noted in the manual page? > I have no idea why the printf's make a difference, unless perhaps your card > needs a bit of a delay after it is inserted before it's firmware is fully > up and running. In that case you might want to insert a delay. Something > like this: > Thanks! The card really needed a delay to setup it's memory right, and i was reading it too soon. (which is also a mistake, because in the original linux driver the config table read is done later from the interrupt handler, when the card has had the time to init it's memory properly.) > /* XXX: Doesn't it want to print rman_get_size() / 1024 instead? */ > device_printf(dev, "card has %uKB memory\n", sc->card_type); the "KB" suffix here is a typo :-/ > count = 0; > while (letoh32(bus_read_4(sc->bar.res, 0)) != CONFIG_MAGIC) { > /* If it's not up after a half-second, give up. */ > if (count > 50) { > device_printf(dev, "ConfigTable Bad!\n"); > return (ENXIO); > } > count++; > > /* Wait 10 ms. */ > DELAY(10000); > } Thanks for the useful info! Best Regards, Niki Denev