Subject: Re: com rumblings...
To: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
From: Garrett D'Amore <garrett_damore@tadpole.com>
List: tech-kern
Date: 06/16/2006 08:27:00
Izumi Tsutsui wrote:
> Sorry for a bit late response, but I'd appreciate if I could have
> more time for review before merge. Thanks,
>
> garrett_damore@tadpole.com wrote:
>
>
>>> - Why don't you put map[] member to struct com_softc?
>>>
>> Because lots of com routines don't actually have/use the softc.
>> Particularly stuff that might be used with console/kgdb support. This
>> common structure lives in the softc, and can also live outside the softc
>> for use in code that doesn't have the softc.
>>
>
> IMHO, it looks a bit inconsistent to have both functions,
> ones take com_softc and the others do com_regs.
> (of course current implementation which passes only iot, ioh
> and iobase is also ugly though)
>
> Actually you have changed such functions (which don't take com_softc)
> into wrapper ones to prepare struct com_regs and create other real
> functions which take struct com_regs.
> Why don't you make them wrapper functions which prepare struct softc?
> How about structures like this?
>
The "old" routines are around for compatibility. Preparing a struct
softc is a bigger deal and may have other impacts. I was shooting for
the least effort, admittedly. But then I wasn't exactly making these
changes in a vacuum either -- there was a lot of preexisting code to modify.
A lot of external MD code used this stuff too.
struct com_regs contains the minimum amount of information to implement
the CSR access routines. Since those other routines that take a handle
and tag do the same thing, rather than adding a new argument to them, I
converted them to take take the com_regs instead.
Actually, I made new ones that could take the com_regs, and left the old
ones around as wrappers to minimize impact on MD code.
> ---
> struct com_regs {
> bus_space_tag_t cr_iot;
> bus_space_handle_t cr_ioh;
> bus_addr_t cr_iobase;
> bus_size_t cr_nports;
> bus_size_t cr_regmap[16];
> };
>
> struct com_softc {
> struct device sc_dev;
> void *sc_si;
> struct tty *sc_tty;
>
> struct callout sc_diag_callout;
>
> int sc_frequency;
>
> struct com_regs sc_regs;
> #define sc_iot sc_regs.cr_iot
> #define sc_ioh sc_regs.cr_ioh
> #define sc_iobase sc_regs.cr_iobase
> #define sc_nports sc_regs.cr_nports
> #define sc_regmap sc_regs.cr_regmap
>
> bus_space_handle_t sc_hayespioh;
> :
>
> ---
> :
> #define CSR_WRITE_1(sc, o, v) \
> bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (sc)->sc_regmap[o], v)
> #define CSR_READ_1(sc, o) \
> bus_space_read_1((sc)->sc_iot, (sc)->cr_ioh, (sc)->cr_map[o])
> :
> int
> cominit(struct com_softc *sc, int rate, int frequency, int type,
> tcflag_t cflag)
> {
>
> if (bus_space_map(sc->sc_iot, sc->sc_iobase, sc->sc_nports, 0,
> &sc->sc_ioh))
> return (ENOMEM); /* ??? */
>
> rate = comspeed(rate, frequency, type);
> if (type != COM_TYPE_AU1x00) {
> /* no EFR on alchemy */
> CSR_WRITE_1(sc, COM_REG_LCR, LCR_EERS);
> :
> }
> :
> int
> comcnattach1(struct com_softc *sc, int rate, int frequency, int type,
> tcflag_t cflag)
> {
> int res;
>
> comconsregs = sc->sc_reg;
>
> res = cominit(sc, rate, frequency, type, cflag);
> :
> }
>
> int
> comcnattach(bus_space_tag_t iot, bus_addr_t iobase, int rate, int frequency,
> int type, tcflag_t cflag)
> {
> struct com_softc sc_store;
> struct com_softc *sc = &sc_store;
>
> sc->sc_iot = iot;
> sc->sc_iobase = iobase;
> sc->sc_nports = COM_NPORTS;
> #ifdef COM_REGMAP
> memcpy(sc->sc_regmap, com_std_map, sizeof(sc->sc_regmap));
> #endif
>
> return comcnattach1(sc, rate, frequency, type, cflag);
> }
>
> ---
>
> In this implementation, you have to copy struct com_regs
> from comconsregs to com_softc for com_common_{put,get}c().
> If you don't like the copy, we could have some hacked
> struct com_regs which can be passed as struct softc:
>
> ---
> struct com_regs {
> /* these members should be sync'ed with ones in struct com_softc */
> struct device cr_dev; /* dummy */
>
> bus_space_tag_t cr_iot;
> bus_space_handle_t cr_ioh;
> bus_addr_t cr_iobase;
> bus_size_t cr_nports;
> bus_size_t cr_regmap[16];
> };
>
> struct com_softc {
> struct device sc_dev;
>
> bus_space_tag_t sc_iot;
> bus_space_handle_t sc_ioh;
> bus_addr_t sc_iobase;
> bus_size_t sc_nports;
> bus_size_t sc_regmap[16];
>
> bus_space_handle_t sc_hayespioh;
>
> void *sc_si;
> struct tty *sc_tty;
>
> struct callout sc_diag_callout;
>
> int sc_frequency;
> :
> ---
>
> I'm not sure if these implementations are good idea
> (because I'm not a programmer but just a dumb reader),
> but I think it could reduce changes from -current common style.
> (note I don't test these changes at all though)
>
Heh. The original com code "deviates" by having these routines which
take a bus_tag_t and a bus_addr_t. Its ugly. I'd like to clean them up
even further, but that is even more change. I'm trying to minimize the
number of changes I have to make. I spent pretty much an entire workday
yesterday touching a bunch of code that I can't even test.
>
>>> - Where is "COM_REGSMAP" defined in your code?
>>>
>> In conf/files (or rather, opt_com.h)
>>
>>
>>> Is it possible to define it only if a particular MD
>>> attachment which requires special layout is configured?
>>>
>> Yes. Stick it in MD config file (e.g. I have it in files.alchemy and
>> files.atheros, but not in i386.)
>>
>
> Hmm. What happens if we have to support another com variant which
> is attached to MI bus but also has odd regster mapping?
>
Then you better define COM_REGSMAP. Right now the "weird" variants are
all on MD busses.
>
>>> - Do all MD attachments have to initialize map[] array
>>> if COM_REGSMAP is defined?
>>>
>> No, there is a default "COM_INIT_REGS" that initializes this for
>> standard 16550 layout.
>>
>
> Well, you are adding COM_INIT_REGS() macro in _all_ MD attachments.
> That was my concern. Some people may complain about it if they have
> their own private drivers, or if you miss some attachments on the merge.
>
> I wonder if we can initialize the regmap array in com_attach_subr()
> according to some proper quirk flag in softc:
> ---
> if ((sc->sc_flags & COM_F_HAVE_OWN_REGMAP) == 0)
> COM_INIT_REGMAP(sc->sc_regmap);
> ---
>
> Then I guess we could use most current MD attachments without
> extra changes.
>
I considered this even. But I decided to go and touch all the MD
attachments, because frankly a bunch of them go and modify the softc
structure directly anyway.
-- Garrett
> ---
> Izumi Tsutsui
>
--
Garrett D'Amore, Principal Software Engineer
Tadpole Computer / Computing Technologies Division,
General Dynamics C4 Systems
http://www.tadpolecomputer.com/
Phone: 951 325-2134 Fax: 951 325-2191