8139too.c (2)
Linux カーネル解析入門の 259p から 261p のあたり、最近の実装では手続き呼び出しの痕跡さえありません。
ちなみに rtl8139_init_one 手続きの中に以下な記述があります。
ioaddr = tp->mmio_addr; assert (ioaddr != NULL); addr_len = read_eeprom (ioaddr, 0, 8) == 0x8129 ? 8 : 6; for (i = 0; i < 3; i++) ((__le16 *) (dev->dev_addr))[i] = cpu_to_le16(read_eeprom (ioaddr, i + 7, addr_len)); memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
EEPROM から mac アドレスを読み出して云々してる処理。この処理で使われている ioaddr は priv な属性の mmio_addr 属性が根拠らしいのですが、これを設定していると思われる rtl8139_init_board 手続きを確認してみます。
rtl8139_init_board 手続き
mmio_addr 属性を云々しているのは以下な記述になっている模様。
ioaddr = pci_iomap(pdev, bar, 0); if (!ioaddr) { dev_err(d, "cannot map %s\n", res[bar].type); if (!use_io) { use_io = true; goto retry; } rc = -ENODEV; goto err_out; } tp->regs_len = io_len; tp->mmio_addr = ioaddr;
pci_iomap 手続きは lib/pci_iomap.c で定義されてます。ここで
- pci_resource_* とか
- IORESOURCE_* とか
- ioremap 手続きとか
駆使されてますね。全部引用してしまえ。
void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) { resource_size_t start = pci_resource_start(dev, bar); resource_size_t len = pci_resource_len(dev, bar); unsigned long flags = pci_resource_flags(dev, bar); if (!len || !start) return NULL; if (maxlen && len > maxlen) len = maxlen; if (flags & IORESOURCE_IO) return __pci_ioport_map(dev, start, len); if (flags & IORESOURCE_MEM) { if (flags & IORESOURCE_CACHEABLE) return ioremap(start, len); return ioremap_nocache(start, len); } /* What? */ return NULL; }
これ、呼び出す前に pci_request_regions 手続きを呼び出しておく必要があるのだろうな、と思ったらその通りでした。これ、struct net_device 型の mmio_addr 属性に設定するナニはこの手続きを使う、という理解で良いのかな。
次
pci_iomap は掘っておくべきな気がしてます。あと、rtl8139_init_board あたりも色々確認を、ということで。