From nobody@FreeBSD.ORG  Sun Jan  2 12:15:58 2000
Return-Path: <nobody@FreeBSD.ORG>
Received: by hub.freebsd.org (Postfix, from userid 32767)
	id 1A4F614DB1; Sun,  2 Jan 2000 12:15:58 -0800 (PST)
Message-Id: <20000102201558.1A4F614DB1@hub.freebsd.org>
Date: Sun,  2 Jan 2000 12:15:58 -0800 (PST)
From: slavoff@bnc.bg
Sender: nobody@FreeBSD.ORG
To: freebsd-gnats-submit@freebsd.org
Subject: Driver for RealTek 8029
X-Send-Pr-Version: www-1.0

>Number:         15845
>Category:       i386
>Synopsis:       [if_ed] [patch] Driver for RealTek 8029
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    imp
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jan  2 12:20:00 PST 2000
>Closed-Date:    Mon Oct 10 09:04:04 MDT 2005
>Last-Modified:  Mon Oct 10 09:04:04 MDT 2005
>Originator:     Veselin Slavov
>Release:        FreeBSD 3.3-STABLE
>Organization:
Home user
>Environment:
>Description:
I have RealTek 8029 card, but unable to find a driver for it.
Kernel found a ed0 device on pci0, but unable to swich the card to full-duplex mode
Please help me!
>How-To-Repeat:

>Fix:


>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: sos 
State-Changed-When: Wed May 30 02:19:02 PDT 2001 
State-Changed-Why:  
4.3 contains a realtek driver.4.3 contains a realtek driver.4.3 contains a realtek driver. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=15845 
State-Changed-From-To: closed->open 
State-Changed-By: kris 
State-Changed-When: Wed May 30 03:39:18 PDT 2001 
State-Changed-Why:  
This is apparently still an issue. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=15845 

From: Kris Kennaway <kris@obsecurity.org>
To: freebsd-gnats-submit@FreeBSD.org
Cc:  
Subject: Re: i386/15845: Driver for RealTek 8029
Date: Wed, 30 May 2001 03:40:30 -0700

 --GID0FwUMdk1T2AWN
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 Content-Transfer-Encoding: quoted-printable
 
 ----- Forwarded message from Przemyslaw Frasunek <venglin@freebsd.lublin.pl=
 > -----
 
 Delivered-To: kkenn@localhost.obsecurity.org
 Date: Wed, 30 May 2001 11:22:26 +0200
 From: Przemyslaw Frasunek <venglin@freebsd.lublin.pl>
 Subject: Re: i386/15845: Driver for RealTek 8029
 In-reply-to: <200105300919.f4U9JP224181@freefall.freebsd.org>; from
  sos@FreeBSD.org on Wed, May 30, 2001 at 02:19:25AM -0700
 To: sos@FreeBSD.ORG, freebsd-bugs@FreeBSD.ORG
 Precedence: bulk
 Delivered-to: kris@freebsd.org
 Delivered-to: freebsd-bugs@freebsd.org
 User-Agent: Mutt/1.2.5i
 List-ID: <freebsd-bugs.FreeBSD.ORG>
 List-Archive: <http://docs.freebsd.org/mail/> (Web Archive)
 List-Help: <mailto:majordomo?subject=3Dhelp> (List Instructions)
 List-Subscribe: <mailto:majordomo?subject=3Dsubscribe%20freebsd-bugs>
 List-Unsubscribe: <mailto:majordomo?subject=3Dunsubscribe%20freebsd-bugs>
 X-Loop: FreeBSD.org
 
 On Wed, May 30, 2001 at 02:19:25AM -0700, sos@FreeBSD.org wrote:
 > Synopsis: Driver for RealTek 8029
 > State-Changed-From-To: open->closed
 > 4.3 contains a realtek driver.4.3 contains a realtek driver.4.3 contains =
 a realtek driver.
 
 This is still problem. ed(4) driver treats RealTek 8029 chip as NE2000 and=
 =20
 doesn't work with full duplex and media autoselect. This was already
 implemented in OpenBSD's ne(4) driver and should be ported here.
 
 --=20
 * Fido: 2:480/124 ** WWW: http://www.frasunek.com/ ** NIC-HDL: PMF9-RIPE *
 * Inet: przemyslaw@frasunek.com ** PGP: D48684904685DF43EA93AFA13BE170BF *
 
 To Unsubscribe: send mail to majordomo@FreeBSD.org
 with "unsubscribe freebsd-bugs" in the body of the message
 
 ----- End forwarded message -----
 
 --GID0FwUMdk1T2AWN
 Content-Type: application/pgp-signature
 Content-Disposition: inline
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.0.6 (FreeBSD)
 Comment: For info see http://www.gnupg.org
 
 iD8DBQE7FM4dWry0BWjoQKURAsrOAKDbkcRNkePUeKRJIyrKocIJtSBSVwCgrMQ8
 dYWN+IyFuzxWEuPevq4jNMc=
 =/bkQ
 -----END PGP SIGNATURE-----
 
 --GID0FwUMdk1T2AWN--
State-Changed-From-To: open->feedback 
State-Changed-By: mike 
State-Changed-When: Sat Jul 21 11:27:11 PDT 2001 
State-Changed-Why:  

Does this problem still occur in newer versions of FreeBSD, 
such as 4.3-RELEASE? 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=15845 

From: "Przemyslaw Frasunek" <venglin@freebsd.lublin.pl>
To: <freebsd-gnats-submit@FreeBSD.org>, <slavoff@bnc.bg>,
	<mike@FreeBSD.org>
Cc:  
Subject: Re: i386/15845: Driver for RealTek 8029
Date: Sun, 22 Jul 2001 11:07:26 +0200

 Yes, the problem still persists in 4.3-RELEASE; ed(4) should support full
 duplex and media autonegotation on Realtek 8029 as ne(4) does it on OpenBSD
 and NetBSD:
 
 sys/dev/pci/if_ne_pci.c:
 
 { PCI_VENDOR_REALTEK,		PCI_PRODUCT_REALTEK_RT8029,
 	  rtl80x9_mediachange,		rtl80x9_mediastatus,
 	  rtl80x9_init_card,		rtl80x9_media_init,
 	  "RealTek 8029" },
 
 sys/dev/ic/rtl80x9.c:
 
 int
 rtl80x9_mediachange(dsc)
 
 void
 rtl80x9_mediastatus(sc, ifmr)
 
 void
 rtl80x9_init_card(sc)
 
 void
 rtl80x9_media_init(sc)
 
 --
 * Fido: 2:480/124 ** WWW: http://www.frasunek.com/ ** NIC-HDL: PMF9-RIPE *
 * Inet: przemyslaw@frasunek.com ** PGP: D48684904685DF43EA93AFA13BE170BF *
 
State-Changed-From-To: feedback->suspended 
State-Changed-By: mike 
State-Changed-When: Sun Jul 22 09:47:49 PDT 2001 
State-Changed-Why:  

The originator's feedback is in the Audit-Trail.  Awaiting fix and 
committer. 


Responsible-Changed-From-To: freebsd-bugs->wpaul 
Responsible-Changed-By: mike 
Responsible-Changed-When: Sun Jul 22 09:47:49 PDT 2001 
Responsible-Changed-Why:  

Over to Bill Paul <wpaul@FreeBSD.org>, author of if_rl.c. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=15845 
Responsible-Changed-From-To: wpaul->freebsd-bugs 
Responsible-Changed-By: mike 
Responsible-Changed-When: Sun Jul 22 12:37:54 PDT 2001 
Responsible-Changed-Why:  

Oops, this is an issue with the if_ed driver. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=15845 

From: "David S. Madole" <david@madole.net>
To: <freebsd-gnats-submit@FreeBSD.org>, <slavoff@bnc.bg>
Cc:  
Subject: Re: i386/15845: Driver for RealTek 8029
Date: Sun, 5 Jan 2003 13:00:19 -0500

 This is a multi-part message in MIME format.
 
 ------=_NextPart_000_0003_01C2B4BA.666F92A0
 Content-Type: text/plain;
 	charset="Windows-1252"
 Content-Transfer-Encoding: 7bit
 
 I have implemented media selection for the Realtek chips under the ed
 driver. I was not fully aware of this PR at the time I did it, but here it
 is, against 4.7-RELEASE.
 
 Note that there are some hardware limitations of these simple chips, most
 notably that there is no way to tell what media options are valid on a given
 card. This code assumes that 10baseT, 10base5, and 10base2 are all always
 present.
 
 There is also no way to detect 10baseT link except to set autoselect and see
 if the card chooses 10base2 instead. On a card that does not have 10base2,
 this would be viable, but because you can't know if 10base2 is present, I
 chose not to attempt to report status at all.
 
 Finally, these chips do not support autonegotiation, so media autoselect
 only supports half-duplex. Full duplex can however be set manually for
 10baseT. This also means that switches that are not able to have the port
 duplex set manually will only work half-duplex with these cards.
 
 Still, it adds a tiny bit more versatility to these crufty old workhorses.
 
 I have tested this on both the RTL8019AS (ISA) and the RTL8029AS (PCI) and
 it seems to work fine, although my PCI card has only 10baseT media and my
 ISA card has only 10baseT and 10base2, so all media types have not been
 verified. Still, it's simple enough that I am confident it works for all
 options.
 
 Thanks,
 David Madole
 
 ------=_NextPart_000_0003_01C2B4BA.666F92A0
 Content-Type: application/octet-stream;
 	name="diff"
 Content-Transfer-Encoding: quoted-printable
 Content-Disposition: attachment;
 	filename="diff"
 
 diff -u ed.orig/if_ed.c ed/if_ed.c
 --- ed.orig/if_ed.c	Fri Nov  2 19:36:07 2001
 +++ ed/if_ed.c	Sun Jan  5 12:13:32 2003
 @@ -87,6 +87,9 @@
  static __inline void	ed_xmit	__P((struct ed_softc *));
  static __inline char *	ed_ring_copy __P((struct ed_softc *, char *, =
 char *,
  					  /* u_short */ int));
 +static int	ed_rtl_set_media	__P((struct ifnet *ifp));
 +static void	ed_rtl_get_media	__P(( struct ifnet *ifp,
 +					struct ifmediareq *));
  static void	ed_hpp_set_physical_link __P((struct ed_softc *));
  static void	ed_hpp_readmem	__P((struct ed_softc *, int, unsigned char =
 *,
  				    /* u_short */ int));
 @@ -1139,6 +1142,152 @@
  	return ed_probe_Novell_generic(dev, flags);
  }
 =20
 +int
 +ed_probe_Realtek(dev, port_rid, flags)
 +	device_t dev;
 +	int port_rid;
 +	int flags;
 +{
 +	struct ed_softc *sc =3D device_get_softc(dev);
 +	int error;
 +
 +	if ((error =3D ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS)))
 +		return (error);
 +
 +	if (!ed_probe_generic8390(sc))
 +		return (ENXIO);
 +
 +	if (ed_nic_inb(sc, ED_P0_CR) & (ED_CR_PS0 | ED_CR_PS1))
 +		ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
 +
 +	if (ed_nic_inb(sc, ED_RTL80X9_80X9ID0) !=3D 0x50)
 +		return (ENXIO);
 +
 +	switch (ed_nic_inb(sc, ED_RTL80X9_80X9ID1)) {
 +	case 0x70:
 +		sc->chip_type =3D ED_CHIP_TYPE_RTL8019;
 +		break;
 +	case 0x43:
 +		sc->chip_type =3D ED_CHIP_TYPE_RTL8029;
 +		break;
 +	default:
 +		return (ENXIO);
 +	}
 +
 +	sc->asic_offset =3D ED_NOVELL_ASIC_OFFSET;
 +	sc->nic_offset  =3D ED_NOVELL_NIC_OFFSET;
 +
 +	if ((error =3D ed_probe_Novell_generic(dev, flags)))
 +		return (error);
 +
 +	ifmedia_init(&sc->ifmedia, 0, ed_rtl_set_media, ed_rtl_get_media);
 +
 +	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T | IFM_FDX, 0, 0);
 +	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T, 0, 0);
 +	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_2, 0, 0);
 +	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_5, 0, 0);
 +	ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_AUTO, 0, 0);
 +
 +	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_3 | ED_CR_STP);
 +
 +	switch (ed_nic_inb(sc, ED_RTL80X9_CONFIG2) & ED_RTL80X9_CF2_MEDIA) {
 +	case ED_RTL80X9_CF2_AUTO:
 +		ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_AUTO);
 +		break;
 +	case ED_RTL80X9_CF2_10_5:
 +		ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_5);
 +		break;
 +	case ED_RTL80X9_CF2_10_2:
 +		ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_2);
 +		break;
 +	case ED_RTL80X9_CF2_10_T:
 +		ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_10_T |
 +			(ed_nic_inb(sc, ED_RTL80X9_CONFIG3)
 +				& ED_RTL80X9_CF3_FUDUP) ? IFM_FDX : 0);
 +		break;
 +	}
 +	return (0);
 +}
 +
 +static int
 +ed_rtl_set_media(ifp)
 +	struct ifnet *ifp;
 +{
 +	struct ed_softc *sc;
 +	int spl;
 +
 +	sc =3D ifp->if_softc;
 +	spl =3D splimp();
 +	ed_nic_outb(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_3
 +		| (ed_nic_inb(sc, ED_P0_CR) & (ED_CR_STA | ED_CR_STP)));
 +
 +	switch(IFM_SUBTYPE(sc->ifmedia.ifm_cur->ifm_media)) {
 +	case IFM_10_T:
 +		ed_nic_outb(sc, ED_RTL80X9_CONFIG2, ED_RTL80X9_CF2_10_T
 +			| (ed_nic_inb(sc, ED_RTL80X9_CONFIG2)
 +				& ~ED_RTL80X9_CF2_MEDIA));
 +		break;
 +	case IFM_10_2:
 +		ed_nic_outb(sc, ED_RTL80X9_CONFIG2, ED_RTL80X9_CF2_10_2
 +			| (ed_nic_inb(sc, ED_RTL80X9_CONFIG2)
 +				& ~ED_RTL80X9_CF2_MEDIA));
 +		break;
 +	case IFM_10_5:
 +		ed_nic_outb(sc, ED_RTL80X9_CONFIG2, ED_RTL80X9_CF2_10_5
 +			| (ed_nic_inb(sc, ED_RTL80X9_CONFIG2)
 +				& ~ED_RTL80X9_CF2_MEDIA));
 +		break;
 +	case IFM_AUTO:
 +		ed_nic_outb(sc, ED_RTL80X9_CONFIG2, ED_RTL80X9_CF2_AUTO
 +			| (ed_nic_inb(sc, ED_RTL80X9_CONFIG2)
 +				& ~ED_RTL80X9_CF2_MEDIA));
 +		break;
 +	}
 +
 +	ed_nic_outb(sc, ED_RTL80X9_CONFIG3,
 +		(sc->ifmedia.ifm_cur->ifm_media & IFM_FDX) ?
 +		(ed_nic_inb(sc, ED_RTL80X9_CONFIG3) | ED_RTL80X9_CF3_FUDUP) :
 +		(ed_nic_inb(sc, ED_RTL80X9_CONFIG3) & ~ED_RTL80X9_CF3_FUDUP));
 +
 +	(void) splx(spl);
 +	return (0);
 +}
 +
 +static void
 +ed_rtl_get_media(ifp, imr)
 +	struct ifnet *ifp;
 +	struct ifmediareq *imr;
 +{
 +	struct ed_softc *sc;
 +	int spl;
 +
 +	sc =3D ifp->if_softc;
 +	imr->ifm_active =3D sc->ifmedia.ifm_cur->ifm_media;
 +
 +
 +	if (IFM_SUBTYPE(imr->ifm_active) =3D=3D IFM_AUTO) {
 +		spl =3D splimp();
 +		ed_nic_outb(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_3 |
 +			(ed_nic_inb(sc, ED_P0_CR) & (ED_CR_STA | ED_CR_STP)));
 +
 +		switch (ed_nic_inb(sc, ED_RTL80X9_CONFIG0)
 +				& (ED_CHIP_TYPE_RTL8029 ? ED_RTL80X9_CF0_BNC
 +				: (ED_RTL80X9_CF0_AUI | ED_RTL80X9_CF0_BNC))) {
 +		case ED_RTL80X9_CF0_BNC:
 +			imr->ifm_active |=3D IFM_10_2;
 +			break;
 +		case ED_RTL80X9_CF0_AUI:
 +			imr->ifm_active |=3D IFM_10_5;
 +			break;
 +		default:
 +			imr->ifm_active |=3D IFM_10_T;
 +			break;
 +		}
 +		(void) splx(spl);
 +	}
 +	imr->ifm_status =3D 0;
 +}
 +
  #define	ED_HPP_TEST_SIZE	16
 =20
  /*
 @@ -2587,6 +2736,12 @@
 =20
  	case SIOCGIFMEDIA:
  	case SIOCSIFMEDIA:
 +		if (sc->chip_type =3D=3D ED_CHIP_TYPE_RTL8019 ||
 +			sc->chip_type =3D=3D ED_CHIP_TYPE_RTL8029) {
 +
 +			error =3D ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
 +			break;
 +		}
  		if (sc->miibus =3D=3D NULL) {
  			error =3D EINVAL;
  			break;
 diff -u ed.orig/if_ed_isa.c ed/if_ed_isa.c
 --- ed.orig/if_ed_isa.c	Mon Jul 29 03:52:57 2002
 +++ ed/if_ed_isa.c	Sun Jan  5 01:06:51 2003
 @@ -40,6 +40,7 @@
  #include <net/if.h>
  #include <net/if_arp.h>
  #include <net/if_mib.h>
 +#include <net/if_media.h>
 =20
  #include <isa/isavar.h>
  #include <isa/pnpvar.h>
 @@ -93,6 +94,11 @@
  	ed_release_resources(dev);
 =20
  	error =3D ed_probe_3Com(dev, 0, flags);
 +	if (error =3D=3D 0)
 +		goto end;
 +	ed_release_resources(dev);
 +
 +	error =3D ed_probe_Realtek(dev, 0, flags);
  	if (error =3D=3D 0)
  		goto end;
  	ed_release_resources(dev);
 diff -u ed.orig/if_ed_pci.c ed/if_ed_pci.c
 --- ed.orig/if_ed_pci.c	Sun Sep 10 04:45:11 2000
 +++ ed/if_ed_pci.c	Sun Jan  5 12:16:44 2003
 @@ -35,6 +35,7 @@
  #include <net/if.h>
  #include <net/if_arp.h>
  #include <net/if_mib.h>
 +#include <net/if_media.h>
 =20
  #include <pci/pcireg.h>
  #include <pci/pcivar.h>
 @@ -84,7 +85,11 @@
          int	flags =3D 0;
          int	error;
 =20
 -        error =3D ed_probe_Novell(dev, PCIR_MAPS, flags);
 +	if (pci_get_devid(dev) =3D=3D 0x802910ec)
 +		error =3D ed_probe_Realtek(dev, PCIR_MAPS, flags);
 +	else
 +		error =3D ed_probe_Novell(dev, PCIR_MAPS, flags);
 +
          if (error)
                  return (error);
 =20
 diff -u ed.orig/if_edreg.h ed/if_edreg.h
 --- ed.orig/if_edreg.h	Wed Jul 25 14:06:01 2001
 +++ ed/if_edreg.h	Sat Jan  4 22:16:59 2003
 @@ -1107,6 +1107,31 @@
  #define ED_CHIP_TYPE_DP8390	0x00
  #define ED_CHIP_TYPE_WD790	0x01
  #define ED_CHIP_TYPE_AX88190	0x02
 +#define ED_CHIP_TYPE_RTL8019	0x03
 +#define ED_CHIP_TYPE_RTL8029	0x04
 +
 +/*
 + * RTL8019/8029 Specific Registers
 + */
 +
 +#define ED_RTL80X9_CONFIG0	0x03
 +#define ED_RTL80X9_CONFIG2	0x05
 +#define ED_RTL80X9_CONFIG3	0x06
 +#define ED_RTL80X9_80X9ID0	0x0a
 +#define ED_RTL80X9_80X9ID1	0x0b
 +
 +#define	ED_RTL80X9_CF0_BNC	0x04
 +#define ED_RTL80X9_CF0_AUI	0x20
 +
 +#define ED_RTL80X9_CF2_MEDIA	0xc0
 +#define ED_RTL80X9_CF2_AUTO	0x00
 +#define ED_RTL80X9_CF2_10_T	0x40
 +#define ED_RTL80X9_CF2_10_5	0x80
 +#define ED_RTL80X9_CF2_10_2	0xc0
 +
 +#define ED_RTL80X9_CF3_FUDUP	0x40
 +
 +#define ED_CR_PAGE_3		0xc0
 =20
  /*
   * AX88190 IOBASE registers.
 diff -u ed.orig/if_edvar.h ed/if_edvar.h
 --- ed.orig/if_edvar.h	Wed Jul 25 14:06:01 2001
 +++ ed/if_edvar.h	Sun Jan  5 01:07:29 2003
 @@ -90,6 +90,8 @@
  	u_char  rec_page_stop;	/* last page of RX ring-buffer */
  	u_char  next_packet;	/* pointer to next unread RX packet */
  	struct	ifmib_iso_8802_3 mibdata; /* stuff for network mgmt */
 +
 +	struct ifmedia ifmedia;	/* resource for media selection */
  };
 =20
  #define	ed_nic_inb(sc, port) \
 @@ -197,6 +199,7 @@
  int	ed_probe_WD80x3		__P((device_t, int, int));
  int	ed_probe_WD80x3_generic	__P((device_t, int, unsigned short *[]));
  int	ed_probe_3Com		__P((device_t, int, int));
 +int	ed_probe_Realtek	__P((device_t, int, int));
  int	ed_probe_Novell		__P((device_t, int, int));
  int	ed_probe_Novell_generic	__P((device_t, int));
  int	ed_probe_HP_pclanp	__P((device_t, int, int));
 
 ------=_NextPart_000_0003_01C2B4BA.666F92A0--
 
State-Changed-From-To: suspended->open 
State-Changed-By: imp 
State-Changed-When: Sat Apr 5 00:27:46 MST 2003 
State-Changed-Why:  
I'll try to integrate the patch and see if I can test it on the 
8029pci that I think I still have. 



Responsible-Changed-From-To: freebsd-bugs->imp 
Responsible-Changed-By: imp 
Responsible-Changed-When: Sat Apr 5 00:27:46 MST 2003 
Responsible-Changed-Why:  
I'll try to integrate the patch and see if I can test it on the 
8029pci that I think I still have. 


http://www.freebsd.org/cgi/query-pr.cgi?pr=15845 
State-Changed-From-To: open->closed 
State-Changed-By: imp 
State-Changed-When: Mon Oct 10 09:03:28 MDT 2005 
State-Changed-Why:  
Applied to current, merged to RELENG_6.  Maybe I'll MFC to 5 someday, 
maybe not. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=15845 
>Unformatted:
