There are five read preferences that drivers and mongos should support when routing queries and getmores:
1. PRIMARY – all reads are directed to the replica set (or shard) primary; if there is no primary, reads are rejected
2. PRIMARY_FIRST – reads are preferentially directed to the replica set primary, but will fall back to a secondary if a primary is not available or reachable
3. SECONDARY_ONLY – all reads are directed to the replica set secondaries; if there are no secondaries, reads are rejected
4. SECONDARY – reads are preferentially directed to the replica set secondaries, but will fall back to the primary if no secondaries are available or reachable
5. ALL – reads are distributed to all replica set nodes, and a client does not know a-priori if the read will go to a primary or secondary
Drivers, and mongos, currently support option #1 (when slave_okay is false), and most drivers support option #3 (when slave_okay is true); old versions of some drivers do not direct reads to secondaries even when slave_okay is true, and so implement #2.
Both drivers and mongos should allow for setting a default read preference and overriding the read preference on a per-request basis, as is currently the case with slave_okay.
For backwards compatibility, the slave_okay bit should be set for modes 3, 4, and 5.
EDIT: Renamed "PRIMARY_ONLY" => "PRIMARY"; "PRIMARY" => "PRIMARY_FIRST"; at least Java driver and Pymongo use ReadPreference.PRIMARY to mean what I had initially called "PRIMARY_ONLY". I think the particular names are less important than the behaviors they encapsulate.