Programatorsky orisek?

Jan Marek jmarek na jcu.cz
Čtvrtek Listopad 1 09:14:53 CET 2001


Dobry den,

zacal jsem se stourat v kernelu, protoze po prechodu na jadro
2.4.12-xfs (mam na nem root filesystem) mi prestalo na laptopu
fungovat PCMCIA. Elegantne se zasekavalo takovym zpusobem, ze uz
nefungovaly ani pomucky typu Magic_Syskeys... Co jsem udelal:
Do driveru pro PCMCIA (soubor drivers/pcmcia/yenta.c) jsem si
doplnil ladici vypisy, abych zjistil, kde dojde k zatuhnuti.
Provedl jsem to ve dvou funkcich, ktere zde predkladam:


--- start of part of file yenta.c
/*
 * Initialize the standard cardbus registers
 */
static void yenta_config_init(pci_socket_t *socket)
{
	u16 bridge;
	struct pci_dev *dev = socket->dev;

	printk("yenta_config_init:\n");
	pci_set_power_state(socket->dev, 0);
	printk("- after pci_set_power_state\n");

	config_writel(socket, CB_LEGACY_MODE_BASE, 0);
	printk("- after 1st config_writel\n");
	config_writel(socket, PCI_BASE_ADDRESS_0, dev->resource[0].start);
	printk("- after 2nd config_writel\n");
	config_writew(socket, PCI_COMMAND,
			PCI_COMMAND_IO |
			PCI_COMMAND_MEMORY |
			PCI_COMMAND_MASTER |
			PCI_COMMAND_WAIT);
	printk("- after config_writew\n");

	/* MAGIC NUMBERS! Fixme */
	config_writeb(socket, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
	printk("- after 1st config_writeb\n");
	config_writeb(socket, PCI_LATENCY_TIMER, 168);
	printk("- after 2nd config_writeb\n");
	config_writel(socket, PCI_PRIMARY_BUS,
		(176 << 24) |			   /* sec. latency timer */
		(dev->subordinate->subordinate << 16) | /* subordinate bus */
		(dev->subordinate->secondary << 8) |  /* secondary bus */
		dev->subordinate->primary);		   /* primary bus */
	printk("- after config_writel\n");

	/*
	 * Set up the bridging state:
	 *  - enable write posting.
	 *  - memory window 0 prefetchable, window 1 non-prefetchable
	 *  - PCI interrupts enabled if a PCI interrupt exists..
	 */
	bridge = config_readw(socket, CB_BRIDGE_CONTROL);
	printk("- after bridge = config_readw\n");
	bridge &= ~(CB_BRIDGE_CRST | CB_BRIDGE_PREFETCH1 | CB_BRIDGE_INTR | CB_BRIDGE_ISAEN | CB_BRIDGE_VGAEN);
	printk("- after bridge &= ~(...\n");
	bridge |= CB_BRIDGE_PREFETCH0 | CB_BRIDGE_POSTEN;
	printk("- after bridge |= CB...\n");
	if (!socket->cb_irq)
		bridge |= CB_BRIDGE_INTR;
	printk("- after if...\n");
	config_writew(socket, CB_BRIDGE_CONTROL, bridge);
	printk("- after config_writew\n");

	exca_writeb(socket, I365_GBLCTL, 0x00);
	printk("- after 1st exca_writeb\n");
	exca_writeb(socket, I365_GENCTL, 0x00);
	printk("- after 2nd exca_writeb\n");

	/* Redo card voltage interrogation */
	cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST); 
	printk("- after last cb_writel\n");
}

/* Called at resume and initialization events */
static int yenta_init(pci_socket_t *socket)
{
	yenta_config_init(socket);
	printk("yenta_config_init OK!\n");
	yenta_clear_maps(socket);
	return 0;
}
--- end of part of file yenta.c

A ted prijde ta zahada: Podle toho, co mi kernel vypisuje, se
projde CELA funkce yenta_config_init() (posledni hlaska je:
- after last cb_writel), ale uz se nevypise hlaska
"yenta_config_init OK!"!!!??? Jak to? To vypada, jako by se
neprovedl navrat z funkce yenta_config_init()??? Nebo je printk()
bufferovany a posledni hlaska se nevypise (i kdyz je na konci
novy radek???)? Nebo se tam stane jeste neco uplne jinyho (ale
co?)? Pokazdy to skonci na stejnem miste, takze je to naprosto
deterministicky (aspon myslim...).

Co na to rikate?

Zdravi
Honza Marek
-- 
Ing. Jan Marek
University of South Bohemia
Academic Computer Centre
Phone: +420-38-7772080


Další informace o konferenci Linux