datasheet 見ながらドライバ眺めてみる

面白い。とりあえず以下の_カード・リセット_の項に出てる以下のコード

static void rtl8139_chip_reset (void __iomem *ioaddr)
{
	int i;

	/* Soft reset the chip. */
	RTL_W8 (ChipCmd, CmdReset);

	/* Check that the chip has finished the reset. */
	for (i = 1000; i > 0; i--) {
		barrier();
		if ((RTL_R8 (ChipCmd) & CmdReset) == 0)
			break;
		udelay (10);
	}
}

まず、RTL_W8 というマクロを掘削。r/w 含め以下に引用。

/* write MMIO register */
#define RTL_W8(reg, val8)	iowrite8 ((val8), ioaddr + (reg))
#define RTL_W16(reg, val16)	iowrite16 ((val16), ioaddr + (reg))
#define RTL_W32(reg, val32)	iowrite32 ((val32), ioaddr + (reg))

/* read MMIO register */
#define RTL_R8(reg)		ioread8 (ioaddr + (reg))
#define RTL_R16(reg)		ioread16 (ioaddr + (reg))
#define RTL_R32(reg)		((unsigned long) ioread32 (ioaddr + (reg)))

ここに出てきてる iowrite とかなソレを掘削。include/asm-generic/io.h にて以下。

#define ioread8(addr)		readb(addr)
#define ioread16(addr)		readw(addr)
#define ioread32(addr)		readl(addr)

#define iowrite8(v, addr)	writeb((v), (addr))
#define iowrite16(v, addr)	writew((v), (addr))
#define iowrite32(v, addr)	writel((v), (addr))

ええと、write* 関連のマクロを掘ってみました。同じソースファイルにて定義。

static inline void __raw_writeb(u8 b, volatile void __iomem *addr)
{
	*(volatile u8 __force *) addr = b;
}

static inline void __raw_writew(u16 b, volatile void __iomem *addr)
{
	*(volatile u16 __force *) addr = b;
}

static inline void __raw_writel(u32 b, volatile void __iomem *addr)
{
	*(volatile u32 __force *) addr = b;
}

#define writeb __raw_writeb
#define writew(b,addr) __raw_writew(__cpu_to_le16(b),addr)
#define writel(b,addr) __raw_writel(__cpu_to_le32(b),addr)

詳細なチェキはスルーさせて頂くとして例えば以下なナニであれば

	/* Soft reset the chip. */
	RTL_W8 (ChipCmd, CmdReset);

ええと、それぞれの symbol の定義が 8139too.c で以下。まず ChipCmd が

	ChipCmd		= 0x37,

で、CmdReset が

	CmdReset	= 0x10,

となってます。これは Offset 0037h なレジスタに 0x10 を書き込むという意味って理解で良いはず。少々 RTL_W8 の ioaddr という変数が微妙ですが。

今日は時間切れ

このあたり穿りかえして色々確認って面白そう。今日同僚との一服話に出てきたんですが、こうしたソースを datasheet と読むのって慣用句的なソレに慣れる、って意味でも面白いし必要なのかも。
でも network device なソレの慣用句に慣れるつもりはないんですが。。