Subject: Re: A TODO list for cardbus/ PCMCIA support.
To: Jonathan Stone <jonathan@DSG.Stanford.EDU>
From: Chris G. Demetriou <cgd@netbsd.org>
List: tech-kern
Date: 06/17/1999 12:24:17
[ Wow, my weasel nature is strong today.  This should probably have
been many messages. ]

Jonathan Stone <jonathan@DSG.Stanford.EDU> writes:
> Nope.  What's meant is more like:
> 
>    cbb at whatever:  cardbus, pcmcia
>    pcic at whatever: pcmcia
> 
> with child pcmcia devices attaching via pcmcia?, and cardbus devices
> attaching via cardbus?.

OK, i'll buy this.  (I think in fact this is what i was promoting the
last time this discussion came around.  8-)


> Hayakawa-san's point is to avoid duplcating the cis-tuple and pcmcia
> functionality almost verbatim, once for pcic bridges and once for
> cardbus bridges.  IF that means we need to add callback methods via
> the parent bridge to access ExCA(?) or whatever registers, fine.  If a
> cardbus bridge is set so that it won't do PCMCIA, then I guess we
> don't support pcmcia (16-bit) cards on it. ? Or do we need a
> pcmcia-device register-access layer that does a CardBus dance?

I don't think I understand what you're suggesting, because you've
muddled many different points together.

re: cis-tuple handling: in order to not duplicate the implentation of
this, what's needed is a way to cope with reading the CIS from:
	* the normal PCMCIA places.
	* the additional places that cardbus lets you get them from
(and, of course, enough code to pick the right place to read it from).

re: PCMCIA device register access: you need to handle three cases:
	* PCMCIA
	* CBB with PCIC-access-compatible registers turned on, when no
	  CBB driver is attached. This is, in fact, just the same as "PCMCIA."
	* CBB (with driver) with PCIC-access-compatible registers
	  turned off.
	* CBB (with driver) with PCIC-access-compatible registers
	  turned on.
The latter pair should be handled identically, with the possible
except that it probably makes sense to _turn off_ the PCIC
compatibility access method in the latter case.

re: supporting 16-bit (PCMCIA) cards on cardbus bridges: unless the
bridge _does not support_ 16-bit cards, you have to support them even
if the PCIC-compatibile register access is disabled.


What this really means is functions provided by the parents to get
CIS information and to access PCMCIA registers.


> One of the design goals here -- one which everyone who's mentioned it
> seems to share -- is to get /away/ from fixing device names to
> specific slots, and to attach them to a given card, irrespective of
> which slot that card may currently be in.  And that's the point where
> I think purely slot-based architectures just dont cut it.

Unclear to me.  As far as I'm concerned, the right way to do this kind
of "same card gets same name" stuff is probably with a user-land
daemon controlling what device name gets attached where, and when.

In the generic case, where i've not configured something specially, if
i pull out one ethernet card and pop in a different one, i want the
old ep0 to go away and the new ep0 to be the new card.


> If (and it's an if) we can rerun autoconfig uration for a given slot,
> in a kernel thread, in response to an interrupt generated at
> card-insertion time, then most (all?) of the attach-tme problems
> simply go away. The big issue left is:

I thought we could already do that.


>       a) where and how to keep the state to make a device
>          (e.g. NIC with a given MAC address) attach with the same
> 	  name when its re-inserted, regardless of wheter its
> 	  in the same slot,

"not in the kernel."  Obviously, I think it will take a bunch of work
to make this all work right, but it's orthogonal to the issue of
making basic removal and insertion work right.

I think the only choice here is 'not in the kernel,' really.  If you
really want your single card to remain ep0, you probably want that to
be true after reboot as well.  Or at least, I would.  8-)


> and
>       b) whether struct devices go away  completely on detach,
>          or whether htey hang around in some `phantom' state.

yes, they go away.  Device not there, struct device not there.

It's harder to do right, but if kernel hacking were easy everybody
would do it.  8-)



FWIW, I think a large part of the problem here is that people who are
trying to solve the problem are trying to solve it as one monolithic
solution rather than doing it as separate, independent steps.
Unfortunately, to be quite frank, that's how we got where we are
today.

I think the right way/set of steps to proceed with the device
attachment issues is:

* make sure you can take one single type of device, any type of
device, and (which the device isn't active, i.e. ifconfig'd down or
not opened) repeatedly plug it in and have the configuration show up &
go away.  I was under the impression that we were relatively close
this point with some types of devices (e.g. com PCMCIA cards).


	* once that works, a parallel track develops:

		* "all of the stuff to make that happen at an
		   arbitrary point in time, when the device is open."

* repeat for other device types, when not active.  For some of them,
this may be tricky because e.g. the network stack might keep
references which aren't currently as well tracked as they should be.


There are issues that will crop up in the autoconfig code, which need
to be solved:

	* insert 1, insert 2, remove 1, insert 1 -> cloning unit #s
	  keep growing.

	* locking issues to prevent data structure corruption when
	  multiple threads are trying to configure/unconfigure devices
	  at the same time.


Once the basic hot-swap functionality is done (first, when disabled,
then when enabled), _then_ you should start worrying about how to
communicate this to user-land and how to allow user-land to drive the
configuration process.  There are other things that need to be
attacked in the same space, like loadable drivers, and, perhaps more
important, loadable configuration.

However, until the basic functionality is working and solid, trying to
go for something much more advanced will only cause more trouble down
the road.


FWIW, the things that I see as being necessary for CardBus support
are, in approximate order:

	* enough the PCI bus space management/"bin packing" to
	  make sure you can arrange for CBBs to be properly mapped.

		-- at this point, if the CBBs have support compatibility
		   register access you can at least use the PCIC
		   driver with them.  It would seem that for many
		   bridges to enable compat. register access they
		   _need_ their register BAR to be mapped.  I did N
		   gross PCI bar hacks for people to make their CBBs
		   function to this minimal level, i.e. _any use of
		   PCMCIA at all for their laptop__.		
	
		
	* the PCMCIA 'access registers via various methods' code.

	* code to cope with CBB's well enough to make provide the same
	  services as PCIC, i.e. allow you to use PCMCIA cards (with
	  the CBB register access method).

		-- at this point you're using PCMCIA cards on CBBs
		   with CBB style register access and enough support
		   from the CBBs to deal with insertions and removals
		   of at least some types of cards.

	* the stuff relating to CIS, i.e. making the existing CIS
	  tuple code cope with variety in its sources of input.
	
	* coping with mapping inserted CB cards, i.e. dealing with
	  their CIS, mapping their BARs, etc.

		-- at this point you're actually using CB cards.

	* coping with unmapping removed or to-be-removed CB cards.

		-- at this point you can remove CB cards.

Note that nowhere in there is there a discussion about warm (kernel
configured, but device not active) and hot (device active) insertion
and removal.  That's for two reasons:

	* aside from the necessary steps of coding the bits correctly
	  to allow insertion and removal, hot insertion and removal
	  should just fall out of this and the other relevant changes
	  that need to be made e.g. to allow PCMCIA to do warm and hot
	  insertion and removal.

	* they're secondary features to being able to actually use the
	  cards.


In terms of parallelization, i see a couple of 'threads' that separate
people can be working on independently:

	* there's the autoconfig fixup thread.

	* there's the PCMCIA warm and hot insertion and removal
	  thread, and as progress is made there the threads that it
	  spawns off.

	* there's the CBB support thread.

The interesting thing is, it sounds like much of the code to do basic
CBB support is mostly written, and just needs to be integrated.
That's good, because that's the largest poorly parallelizable chunk of
the task.  (making warm and hot insertion and removal work is
potentially huge, but parallelizable.)

I recognize that there's a bunch of CardBus code written, and the
natural desire is to drop it in an make it go as-is.  However, (from
discussion; i've not more than glanced at the code itself) I think the
correct way to integrate it is via the steps outlined above, or a
similar set of steps.  In particular, i think the 'milestones' above
are a good set of ones to shoot for.  (That's not to say that you
can't drop the code in and make it go, but you shouldn't be trying for
the 'use cardbus cards' milestone before you've hit the previous
ones.)



BTW, in case it's not clear, I'd _really_ like CardBus support in the
tree.  I've got a cardbus laptop that's a few years old now, and i'd
_really_ like to be able to use a decent ethernet controller in it...
8-)


cgd
-- 
Chris Demetriou - cgd@netbsd.org - http://www.netbsd.org/People/Pages/cgd.html
Disclaimer: Not speaking for NetBSD, just expressing my own opinion.