GCT GDM72xx WiMAX chip (5)
gdm_usb.c で定義されてる gdm_usb_receive 手続きについて掘削対応。
とりあえず
このあたり
static int gdm_usb_receive(void *priv_dev, void (*cb)(void *cb_data, void *data, int len), void *cb_data) { struct usbwm_dev *udev = priv_dev; struct usb_device *usbdev = udev->usbdev; struct rx_cxt *rx = &udev->rx; struct usb_rx *r; unsigned long flags; if (!udev->usbdev) { dev_err(&usbdev->dev, "%s: No such device\n", __func__); return -ENODEV; }
昨晩確認したのですが、引数な priv_dev は gdm_usb_probe あたりで準備されます。usbdeb 属性については gdm_usb_probe に渡される struct usb_interface オブジェクトから interface_to usbdev 手続きで取得されたものが設定されているはず。
また、rx 属性についても gdm_usb_probe 手続きから呼び出されている init_usb 手続きで初期設定されてます。
- rx->free_list および rx->used_list は INIT_LIST_HEAD で初期化
- rx->lock は spin_lock_init 手続きで初期化
- rx 自体は alloc_rx_struct 手続きで初期化
- urb 属性と buf 属性なオブジェクトが生成されてますね
初期化自体は済んでいるので struct rx_cxt 型な udev->rx から struct usb_rx オブジェクトを取り出しています。spin_lock 付き。
spin_lock_irqsave(&rx->lock, flags); r = get_rx_struct(rx); spin_unlock_irqrestore(&rx->lock, flags);
get_rx_struct 手続きで何をしているか、というと基本的には free_list 属性から struct usb_rx 型な要素を取り出して云々、なのか (引用略)。
で、後は引数でもらってきた callback な関数ポインタと struct nic なオブジェクトを設定して
r->callback = cb; r->cb_data = cb_data;
usb_fill_bulk_urb 手続きを呼び出して urb な要求を submit しているのか。
usb_fill_bulk_urb(r->urb, usbdev, usb_rcvbulkpipe(usbdev, 0x82), r->buf, RX_BUF_SIZE, gdm_usb_rcv_complete, r); return usb_submit_urb(r->urb, GFP_ATOMIC);
こいつらが具体的に何を要求しているのか、は今から確認となります。
urb 要求
そもそもこの usb_fill_bulk_urb という手続きが何なのか、という話なんですが、とりあえず手続き定義のコメントを確認してみます。
* usb_fill_bulk_urb - macro to help initialize a bulk urb * @urb: pointer to the urb to initialize. * @dev: pointer to the struct usb_device for this urb. * @pipe: the endpoint pipe * @transfer_buffer: pointer to the transfer buffer * @buffer_length: length of the transfer buffer * @complete_fn: pointer to the usb_complete_t function * @context: what to set the urb context to. * * Initializes a bulk urb with the proper information needed to submit it * to a device.
あ、思いだした。この手続きは第一引数な urb オブジェクトに以降の引数を設定する手続きでした。手続き部分のみ引用してみます。
urb->dev = dev; urb->pipe = pipe; urb->transfer_buffer = transfer_buffer; urb->transfer_buffer_length = buffer_length; urb->complete = complete_fn; urb->context = context;
以下なカンジになるのか。
- urb->dev には usbdev
- urb->pipe には usb_rcvbulkpipe(usbdev, 0x82)
- urb->transfer_buffer には r->buf
- urb->transfer_buffer_length には RX_BUF_SIZE
- urb->complete には gdm_usb_rcv_complete
- urb->context には r
セットするだけ、ということはやっぱ次の usb_submit_urb がキモなのか。
return usb_submit_urb(r->urb, GFP_ATOMIC);
手続き定義のコメントがやたらに長い。つうか結局ここが核心なのか。とりあえず urb.c の usb_submit_urb な手続き定義のコメント確認します。