Date: Thu, 01 Jan 2009 16:45:37 +0300 From: Roman Kurakin <rik@inse.ru> To: "M. Warner Losh" <imp@bsdimp.com> Cc: rik@FreeBSD.org, svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org Subject: Re: svn commit: r186520 - head/sys/dev/puc Message-ID: <495CC901.7080304@localhost.inse.ru> In-Reply-To: <20090101.000643.1543764949.imp@bsdimp.com> References: <200812271522.mBRFMMHY074982@svn.freebsd.org> <20081229.114241.756909212.imp@bsdimp.com> <495B406F.2040305@localhost.inse.ru> <20090101.000643.1543764949.imp@bsdimp.com>
next in thread | previous in thread | raw e-mail | index | archive | help
M. Warner Losh wrote: > In message: <495B406F.2040305@localhost.inse.ru> > Roman Kurakin <rik@inse.ru> writes: > : M. Warner Losh wrote: > : > In message: <200812271522.mBRFMMHY074982@svn.freebsd.org> > : > Roman Kurakin <rik@FreeBSD.org> writes: > : > : Author: rik > : > : Date: Sat Dec 27 15:22:22 2008 > : > : New Revision: 186520 > : > : URL: http://svn.freebsd.org/changeset/base/186520 > : > : > : > : Log: > : > : Add support for the Oxford OX16PCI958-based card. > : > : > : > : Note, that the patch provided with this card for the Linux states that > : > : the card uses DEFAULT_RCLK * 2, while in fact it is '* 10'. So probably > : > : we should also use the subdevice/subvendord here. For now just ignore > : > : that fact. > : > > : > I've had problems with doing that on some Oxford based cards. The > : > vendor that uses them doesn't set them up, so you can't tell my > : > cardbus oxford card from the pcie oxford card that someone else sent > : > me patches for: both with different clock multipliers... > : > > : Probably we need to implement AUTODETECT_RCLK. I've had the patch, > : but it worked only for modules, cause there was no working timers while the > : cards probe time if the driver was compiled in. I've planned to move > : detection > : code to the first open and do some cleanup after the detection, but > : didn't do > : that. > > I'd like to see that. I think we can defer the detection of RCLK to > The initial code, that was the part of the Cronyx patch for sio(4), is smth like this one excerpt: +#undef inb +#undef outb +#define inb(port) sio_inb (port) +#define outb(port,val) sio_outb (port, val) + +static __inline u_char +sio_getreg (com, off) + struct com_s *com; + bus_size_t off; +{ + if ((unsigned) com->bsh & ~0xffff) + return *(volatile u_char*) (com->bsh + off); + return bus_space_read_1 (com->bst, com->bsh, off); +} + +static __inline void +sio_setreg (com, off, val) + struct com_s *com; + bus_size_t off; + u_char val; +{ + if ((unsigned) com->bsh & ~0xffff) + *(volatile u_char*) (com->bsh + off) = val; + else + bus_space_write_1 (com->bst, com->bsh, off, val); +} + +/* * handle sysctl read/write requests for console speed * * In addition to setting comdefaultrate for I/O through /dev/console, @@ -475,6 +548,181 @@ return (0); } +#define VOLATILE_INT *(volatile int *)& +/* + * Find the oscillator frequency of the UART. + */ +static int +sio_find_freq(com) + struct com_s *com; +{ + int t0, n; + u_char lsr; + + /* Set the loopback mode, 57600 baud. */ + outb(com->int_ctl_port, 0); + sio_setreg(com, com_cfcr, CFCR_DLAB); + sio_setreg(com, com_dlbh, 0); + sio_setreg(com, com_dlbl, 2); + sio_setreg(com, com_cfcr, CFCR_8BITS); + sio_setreg(com, com_fifo, 0); + outb(com->modem_ctl_port, MCR_LOOPBACK); + (void) inb (com->line_status_port); + + /* Catch the tick. */ + t0 = VOLATILE_INT ticks; + while (VOLATILE_INT ticks == t0) + continue; + + /* Run until the next tick, transmitting data. */ + n = 0; + t0 = VOLATILE_INT ticks; + while (VOLATILE_INT ticks == t0) { + lsr = inb (com->line_status_port); + if (lsr & LSR_TXRDY) + sio_setreg(com, com_data, 0x5A); + + if (lsr & LSR_RXRDY) { + (void) inb (com->data_port); + ++n; + } + } + outb(com->modem_ctl_port, com->mcr_image); + sio_setreg(com, com_cfcr, com->cfcr_image); + sio_setreg(com, com_fifo, FIFO_RCV_RST | FIFO_XMT_RST | + com->fifo_image); + if (COM_IIR_TXRDYBUG(com->flags)) { + outb(com->int_ctl_port, IER_ERXRDY | IER_ERLS + | IER_EMSC); + } else { + outb(com->int_ctl_port, IER_ERXRDY | IER_ETXRDY + | IER_ERLS | IER_EMSC); + } + + n = (n * hz + 5760/2) / 5760; + if (n > 4) return 8 * 1843200; + if (n > 2) return 4 * 1843200; + if (n > 1) return 2 * 1843200; + return DEFAULT_RCLK; +} One of the multiport Cronyx card has the hardware switch to change the clock, and before such patch more than a half of requests for support was due to incorrect speeds, cause users didn't understand what they were doing by this switch and how the software should be configured based on its value. > later. How accurate is this, btw? How dependent on timing of > Do we need very strict accuracy here? For the detection of the multiplier before DEFAULT_RCLK it should be enough IMHO. rik > interrupts is it? > > Warner >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?495CC901.7080304>