usb 云々
なんか以前 pl2303 なドライバ読みかけて頓挫しているな、と思いつつ staging なナニも確認しながら読んでみて、と思いたち pl2303.c を開いてみてびっくり。エントリポイントが見当りませんorz
ちなみに読んでるのは 10.4 版くらいの linux-next なツリーだったりしてます。
わわわわ、と言いつつ以下を掘ってみたらなんとなく当たりなカンジ。
module_usb_serial_driver(serial_drivers, id_table);
渡されているソレはとりあえずスルーで。最終てきに以下な記述に置換されるみたい。
#define usb_serial_module_driver(__name, __serial_drivers, __ids) \ static int __init usb_serial_module_init(void) \ { \ return usb_serial_register_drivers(__serial_drivers, \ __name, __ids); \ } \ module_init(usb_serial_module_init); \ static void __exit usb_serial_module_exit(void) \ { \ usb_serial_deregister_drivers(__serial_drivers); \ } \ module_exit(usb_serial_module_exit);
エントリポイントは usb_serial_module_init 手続き。の中で呼び出されている usb_serial_register_drivers 手続きか。
つうかこのあたり、結構激しく変更かかっているようなのかどうか。
ちなみに
staging 配下の comedi な usbdux.c とかも並列で読んでみます。こいつとかだと
module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver);
みたいなマクロを呼び出してますね。掘削してみるに定義は以下らしい。
#define module_comedi_usb_driver(__comedi_driver, __usb_driver) \ module_driver(__comedi_driver, comedi_usb_driver_register, \ comedi_usb_driver_unregister, &(__usb_driver))
module_driver というマクロは共通なのかどうか。include/linux/device.h で以下な定義な模様。
#define module_driver(__driver, __register, __unregister, ...) \ static int __init __driver##_init(void) \ { \ return __register(&(__driver) , ##__VA_ARGS__); \ } \ module_init(__driver##_init); \ static void __exit __driver##_exit(void) \ { \ __unregister(&(__driver) , ##__VA_ARGS__); \ } \ module_exit(__driver##_exit);
最終的にエントリポイントは comedi_usb_driver_register 手続きらしい。最終的に drivers/usb/core/driver.c で定義されている usb_register_driver 手続きを呼び出しています (usb_register というマクロで wrap されてます)。
ちょっと不思議なんですが usb_driver 構造体の drvwrap という属性を使って driver_register 手続きを呼び出してます。一旦スルーで usbserial 方面に戻ります。
usb_serial_register_drivers 手続き
ここからも usb_register なソレを呼び出してます。ここではそのまんま usb_driver 構造体なオブジェクトを渡してらっしゃいますね。で、実はこのあたりはスルーして .probe な手続き定義を確認。つうか何が確認したいかというと callback で渡されるオブジェクトとか struct device 型のオブジェクトの取り出し方について云々だったりして。
まず、usbserial な .probe ですが以下。
static int usb_serial_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct device *ddev = &interface->dev; struct usb_device *dev = interface_to_usbdev(interface);
ddev というローカル変数を dev_* なナニに渡しています。他の callback も確認を。
udriver->suspend = usb_serial_suspend; udriver->resume = usb_serial_resume; udriver->probe = usb_serial_probe; udriver->disconnect = usb_serial_disconnect;
.suspend では struct device なオブジェクトは取り出していないです。.resume も同様。.disconnect でも .probe と同じ取り出し方してますね。
逆に pl2303 マターなナニはどうか、というと例えば pl2303_open だと
static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
引数 port の dev 属性のポインタを渡しています。
if (result) { dev_err(&port->dev, "%s - failed submitting interrupt urb," " error %d\n", __func__, result); return result; }
あるいは ioctl なソレだと以下な形になってて
static int pl2303_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct serial_struct ser; struct usb_serial_port *port = tty->driver_data; dev_dbg(&port->dev, "%s cmd = 0x%04x\n", __func__, cmd);
これでも OK なんですね。たまにどっちでも良さげな時があって悩ましかった記憶あり。
comedi なナニ
ええと、usb なソレは usb_interface 構造体なソレを使わんと、なのかな。微妙なカンジですがダウトなら却下されるとゆーことで (を