GCT GDM72xx WiMAX chip (3)

意味なくシリーズにするクセも微妙だな、と思いつつ。
とりあえず gdm_wimax.c の *register_wimax_device 手続き確認。

register_wimax_device 手続き

まず、alloc_netdev 手続きで struct net_device オブジェクトを取得しています。

	dev = (struct net_device *)alloc_netdev(sizeof(*nic),
						"wm%d", ether_setup);

	if (dev == NULL) {

ちょっとざっくり手順ベースで列挙してみます。

  • struct net_device オブジェクト生成と初期化
  • struct nic オブジェクトの位置を struct net_device オブジェクトから取得して領域初期化など
  • gdm_wimax_event_init 手続き呼び出し
  • register_netdev に struct net_device オブジェクトを渡して登録処理
  • その他初期処理
    • LOOPBACK_TEST マクロの値によって云々
    • 必要であれば gdm_qos_init 手続き呼び出し
    • start_rx_proc 手続き呼び出し
    • gdm_wimax_prepare_device 手続き呼び出し
start_rx_proc 手続き

以下なカンジで呼び出し。

	start_rx_proc(nic);

定義が以下。

static void start_rx_proc(struct nic *nic)
{
	gdm_wimax_rcv_with_cb(nic, prepare_rx_complete, nic);
}

もひとつ掘削。

#define gdm_wimax_rcv_with_cb(n, c, b)	\
	(n->phy_dev->rcv_func)(n->phy_dev->priv_dev, c, b)

ええと、nic->pht_dev は register_wimax_device に渡される引数が設定されてますね。

	nic->phy_dev = phy_dev;

usb 側になっちゃいますが、gdm_usb.c の gdm_usb_probe 手続きで以下な初期設定になっております。

	phy_dev->priv_dev = (void *)udev;
	phy_dev->send_func = gdm_usb_send;
	phy_dev->rcv_func = gdm_usb_receive;

phy_dev->priv_dev に設定されてるソレは gdm_usb_probe 手続きで初期設定されてる模様です。で、その初期設定が終わってから register_wimax_device 手続きを呼び出しているのか。
む、そゆ意味では usb と sdio という切り分けが必要なのでこんな抽象化も必要になってきているのか。なかなかに凄いな。
そりゃ良いのですが、gdm_usb_receive 手続きの中で

  • usb_fill_bulk_urb 手続き
  • usb_submit_urb 手続き

が呼び出されています。こいつら一体何をしてるんでしょ。ちなみに urb という用語の意味は承知しております。

割り込み後

再度復帰。確認したところ、usb_fill_bulk_urb 手続きは第一引数で渡される struct urb なオブジェクトの属性に残りの引数をセットする手続きな模様です (include/linux/usb.h にて定義)。

	usb_fill_bulk_urb(r->urb,
			usbdev,
			usb_rcvbulkpipe(usbdev, 0x82),
			r->buf,
			RX_BUF_SIZE,
			gdm_usb_rcv_complete,
			r);

そういった意味では struct usb_rx なポインタの r という変数に設定されるソレが気になりますな。

	spin_lock_irqsave(&rx->lock, flags);
	r = get_rx_struct(rx);
	spin_unlock_irqrestore(&rx->lock, flags);

排他かけて取得されておりますが、get_rx_struct という手続きは何か、というと同名のソレが gdm_usb.c および gdm_sdio.c で定義されています。両方同時に使えない所以というのはここにもあるんですね。
usb な実装だと struct rx_cxt なオブジェクトの free_list という属性を云々しています。つうか色々な前提が諸々で微妙だなぁ。要は rx なバッファを確保して非同期に受信する用意をしておいて submit という理解で良いのかどうか。
あとは非同期通信が完了したら gdm_usb_rcv_complete な手続きが呼び出されるのだろうな。全部類推だけど。

ちょっと戻ります

gdm_wimax_event_init 手続き呼び出しのあたり。ええと、gdm_wimax.c プライベートな構造体オブジェクトがいらっしゃいます。

static struct {
	int ref_cnt;
	struct sock *sock;
	struct list_head evtq;
	spinlock_t evt_lock;

	struct list_head freeq;
	struct work_struct ws;
} wm_event;

gdm_wimax.c はこいつの操作が中心な部分もあると見てて良いのかどうか。とりあえず gdm_wimax_event_init 手続きはこいつの初期化ですね。で、register_wimax_device 手続きの最後に呼び出されている gdm_wimax_prepare_device 手続きですが、wimax なデバイスの制御情報をどこかに送信しているのかどうなのか。

むむ

どうもこの priv_dev というナニが理解できていないのかどうか。Documentation/usb あたりを確認した方が良いんスかね。
つーことで、当分ゆるーく usb なドキュメントを確認しつつパッチを云々、ってことで時間を使おうと思ってます。Lions' リハビリも必要だし (ぇ