drivers/pcmcia/cistpl.c
Source file repositories/reference/linux-study-clean/drivers/pcmcia/cistpl.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pcmcia/cistpl.c- Extension
.c- Size
- 35874 bytes
- Lines
- 1611
- Domain
- Driver Families
- Bucket
- drivers/pcmcia
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/moduleparam.hlinux/kernel.hlinux/string.hlinux/major.hlinux/errno.hlinux/timer.hlinux/slab.hlinux/mm.hlinux/pci.hlinux/ioport.hlinux/io.hlinux/security.hasm/byteorder.hlinux/unaligned.hpcmcia/ss.hpcmcia/cisreg.hpcmcia/cistpl.hpcmcia/ds.hcs_internal.h
Detected Declarations
struct tuple_flagsfunction release_cis_memfunction set_cis_mapfunction pcmcia_read_cis_memfunction pcmcia_write_cis_memfunction read_cis_cachefunction list_for_each_entryfunction remove_cis_cachefunction destroy_cis_cachefunction list_for_each_safefunction verify_cis_cachefunction pcmcia_replace_cisfunction pccard_get_first_tuplefunction follow_linkfunction pccard_get_next_tuplefunction pccard_get_tuple_datafunction parse_devicefunction parse_checksumfunction parse_longlinkfunction parse_longlink_mfcfunction parse_stringsfunction parse_vers_1function parse_altstrfunction parse_jedecfunction parse_manfidfunction parse_funcidfunction parse_funcefunction parse_configfunction parse_cftable_entryfunction parse_device_geofunction parse_vers_2function parse_orgfunction parse_formatfunction pcmcia_parse_tuplefunction pccard_validate_cisfunction pccard_extract_cisfunction pccard_show_cisfunction pccard_store_cisexport pcmcia_parse_tuple
Annotated Snippet
struct tuple_flags {
u_int link_space:4;
u_int has_link:1;
u_int mfc_fn:3;
u_int space:4;
};
#define LINK_SPACE(f) (((struct tuple_flags *)(&(f)))->link_space)
#define HAS_LINK(f) (((struct tuple_flags *)(&(f)))->has_link)
#define MFC_FN(f) (((struct tuple_flags *)(&(f)))->mfc_fn)
#define SPACE(f) (((struct tuple_flags *)(&(f)))->space)
int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
tuple_t *tuple)
{
if (!s)
return -EINVAL;
if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS))
return -ENODEV;
tuple->TupleLink = tuple->Flags = 0;
/* Assume presence of a LONGLINK_C to address 0 */
tuple->CISOffset = tuple->LinkOffset = 0;
SPACE(tuple->Flags) = HAS_LINK(tuple->Flags) = 1;
if ((s->functions > 1) && !(tuple->Attributes & TUPLE_RETURN_COMMON)) {
cisdata_t req = tuple->DesiredTuple;
tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
if (pccard_get_next_tuple(s, function, tuple) == 0) {
tuple->DesiredTuple = CISTPL_LINKTARGET;
if (pccard_get_next_tuple(s, function, tuple) != 0)
return -ENOSPC;
} else
tuple->CISOffset = tuple->TupleLink = 0;
tuple->DesiredTuple = req;
}
return pccard_get_next_tuple(s, function, tuple);
}
static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
{
u_char link[5];
u_int ofs;
int ret;
if (MFC_FN(tuple->Flags)) {
/* Get indirect link from the MFC tuple */
ret = read_cis_cache(s, LINK_SPACE(tuple->Flags),
tuple->LinkOffset, 5, link);
if (ret)
return -1;
ofs = get_unaligned_le32(link + 1);
SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
/* Move to the next indirect link */
tuple->LinkOffset += 5;
MFC_FN(tuple->Flags)--;
} else if (HAS_LINK(tuple->Flags)) {
ofs = tuple->LinkOffset;
SPACE(tuple->Flags) = LINK_SPACE(tuple->Flags);
HAS_LINK(tuple->Flags) = 0;
} else
return -1;
if (SPACE(tuple->Flags)) {
/* This is ugly, but a common CIS error is to code the long
link offset incorrectly, so we check the right spot... */
ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
if (ret)
return -1;
if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
(strncmp(link+2, "CIS", 3) == 0))
return ofs;
remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5);
/* Then, we try the wrong spot... */
ofs = ofs >> 1;
}
ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
if (ret)
return -1;
if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
(strncmp(link+2, "CIS", 3) == 0))
return ofs;
remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5);
return -1;
}
int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
tuple_t *tuple)
{
Annotation
- Immediate include surface: `linux/module.h`, `linux/moduleparam.h`, `linux/kernel.h`, `linux/string.h`, `linux/major.h`, `linux/errno.h`, `linux/timer.h`, `linux/slab.h`.
- Detected declarations: `struct tuple_flags`, `function release_cis_mem`, `function set_cis_map`, `function pcmcia_read_cis_mem`, `function pcmcia_write_cis_mem`, `function read_cis_cache`, `function list_for_each_entry`, `function remove_cis_cache`, `function destroy_cis_cache`, `function list_for_each_safe`.
- Atlas domain: Driver Families / drivers/pcmcia.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.