책이 dwc_otg_driver.c의 request_irq로 인터럽트를 등록을 설명했다. 그러나, 라즈베리 파이4가 dwc-otg_driver.c 함수를 사용하지 않는다. 있긴 있는데, 4로 오면서 의도적으로 사용하지 않는 듯 하다. 아무리 찾아봐도 request_irq를 dump_stack 메세지에서 찾을 수 없다. 내가 본 메세지는 다음과 같다.
Jun 14 07:38:24 raspberrypi kernel: [ 0.547246] xhci_hcd 0000:01:00.0: hcc params 0x002841eb hci version 0x100 quirks 0x0000001000000890 Jun 14 07:38:24 raspberrypi kernel: [ 0.550250] [+][irq_debug] irq_num: 53, func: request_threaded_irq, line: 1888, caller: xhci_run+0x240/0x670 Jun 14 07:38:24 raspberrypi kernel: [ 0.552941] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.19.127-v7l+ #78 Jun 14 07:38:24 raspberrypi kernel: [ 0.555588] Hardware name: BCM2835 Jun 14 07:38:24 raspberrypi kernel: [ 0.558290] [<c0212dd8>] (unwind_backtrace) from [<c020d3ec>] (show_stack+0x20/0x24) Jun 14 07:38:24 raspberrypi kernel: [ 0.561023] [<c020d3ec>] (show_stack) from [<c09c01dc>] (dump_stack+0xd8/0x11c) Jun 14 07:38:24 raspberrypi kernel: [ 0.563706] [<c09c01dc>] (dump_stack) from [<c0285ae0>] (request_threaded_irq+0x1b4/0x1b8) Jun 14 07:38:24 raspberrypi kernel: [ 0.566425] [<c0285ae0>] (request_threaded_irq) from [<c07b4530>] (xhci_run+0x240/0x670) Jun 14 07:38:24 raspberrypi kernel: [ 0.569178] [<c07b4530>] (xhci_run) from [<c079bd6c>] (usb_add_hcd+0x324/0x7ac) Jun 14 07:38:24 raspberrypi kernel: [ 0.571892] [<c079bd6c>] (usb_add_hcd) from [<c07afa84>] (usb_hcd_pci_probe+0x278/0x398) Jun 14 07:38:24 raspberrypi kernel: [ 0.574625] [<c07afa84>] (usb_hcd_pci_probe) from [<c07cc760>] (xhci_pci_probe+0x3c/0x180) Jun 14 07:38:24 raspberrypi kernel: [ 0.577382] [<c07cc760>] (xhci_pci_probe) from [<c067d008>] (pci_device_probe+0xb0/0x138) Jun 14 07:38:24 raspberrypi kernel: [ 0.580118] [<c067d008>] (pci_device_probe) from [<c0718f3c>] (really_probe+0x20c/0x2cc) Jun 14 07:38:24 raspberrypi kernel: [ 0.582911] [<c0718f3c>] (really_probe) from [<c07191d0>] (driver_probe_device+0x70/0x188) Jun 14 07:38:24 raspberrypi kernel: [ 0.585734] [<c07191d0>] (driver_probe_device) from [<c07193e4>] (__driver_attach+0xfc/0x100) Jun 14 07:38:24 raspberrypi kernel: [ 0.588587] [<c07193e4>] (__driver_attach) from [<c0716e48>] (bus_for_each_dev+0x84/0xc4) Jun 14 07:38:24 raspberrypi kernel: [ 0.591438] [<c0716e48>] (bus_for_each_dev) from [<c07187c8>] (driver_attach+0x2c/0x30) Jun 14 07:38:24 raspberrypi kernel: [ 0.594277] [<c07187c8>] (driver_attach) from [<c0718248>] (bus_add_driver+0x1d0/0x214) Jun 14 07:38:24 raspberrypi kernel: [ 0.597086] [<c0718248>] (bus_add_driver) from [<c0719bc4>] (driver_register+0x84/0x118) Jun 14 07:38:24 raspberrypi kernel: [ 0.599945] [<c0719bc4>] (driver_register) from [<c067c2e0>] (__pci_register_driver+0x58/0x5c) Jun 14 07:38:24 raspberrypi kernel: [ 0.602852] [<c067c2e0>] (__pci_register_driver) from [<c0e3f6cc>] (xhci_pci_init+0x68/0x6c) Jun 14 07:38:24 raspberrypi kernel: [ 0.605785] [<c0e3f6cc>] (xhci_pci_init) from [<c0203004>] (do_one_initcall+0x50/0x220) Jun 14 07:38:24 raspberrypi kernel: [ 0.608748] [<c0203004>] (do_one_initcall) from [<c0e01374>] (kernel_init_freeable+0x340/0x3e0) Jun 14 07:38:24 raspberrypi kernel: [ 0.611723] [<c0e01374>] (kernel_init_freeable) from [<c09d5590>] (kernel_init+0x18/0x128) Jun 14 07:38:24 raspberrypi kernel: [ 0.614684] [<c09d5590>] (kernel_init) from [<c02010ac>] (ret_from_fork+0x14/0x28) Jun 14 07:38:24 raspberrypi kernel: [ 0.617678] Exception stack(0xefa61fb0 to 0xefa61ff8)
- 일단 request_threaded_irq가 request_irq임은 확실하다.
- xhci_run이 request_threaded_irq를 호출한다.
- usb_add_hcd가 xhci_run을 호출한다.
- … 이런 식으로 kernel_init로 간다.
- 결국 시스템 시작할 때 인터럽트를 등록한다.
문제가 책 예시와 다르게, 누가 request_irq를 실행하는지 모르는 점이다. dump_stack이 미리 정의되지 않은 함수는 보여주지 않는 듯 하다. 찾아보면 알겠지만 msi가 드라이버를 만들었다. xhci_run, usb_add_hcd, usb_hcd_pci_probe 등 여러 함수 중 request_irq를 콜하는 부분을 쉽게 찾을 수 없었다. 그러나 시간이 많은 나는 결국 xhci_run의 xhci_setup_msi가 requset_irq를 함을 찾아냈다.
/* * Set up MSI */ static int xhci_setup_msi(struct xhci_hcd *xhci) { int ret; /* * TODO:Check with MSI Soc for sysdev */ struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI); if (ret < 0) { xhci_dbg_trace(xhci, trace_xhci_dbg_init, "failed to allocate MSI entry"); return ret; } ret = request_irq(pdev->irq, xhci_msi_irq, 0, "xhci_hcd", xhci_to_hcd(xhci)); //210611 irq 추가... interrupt_debug_irq_desc(pdev->irq); if (ret) { xhci_dbg_trace(xhci, trace_xhci_dbg_init, "disable MSI interrupt"); pci_free_irq_vectors(pdev); } return ret; }
이렇게 설정 후 컴파일 하면, 메세지가 제대로 출력된다. 교재와 다르게 인터럽트 53번으로 설정한다.
Jun 14 07:38:24 raspberrypi kernel: [ 0.626769] 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000 Jun 14 07:38:24 raspberrypi kernel: [ 0.629855] genirq: irq_chip Brcm_MSI did not update eff. affinity mask of irq 53 Jun 14 07:38:24 raspberrypi kernel: [ 0.632884] [+] irq_desc debug start Jun 14 07:38:24 raspberrypi kernel: [ 0.635920] irq num: 53 name: xhci_hcd Jun 14 07:38:24 raspberrypi kernel: [ 0.638938] dev_id:0xefa55000 Jun 14 07:38:24 raspberrypi kernel: [ 0.641924] interrupt handler: xhci_msi_irq+0x0/0x20 Jun 14 07:38:24 raspberrypi kernel: [ 0.644914] [-] irq_desc debug end
몇 번 해보면서 느꼈는데, 꼬리에 꼬리를 물어 원하는 부분을 찾아내는 능력이 필요해 보인다. 그래야 그 부분을 수정하여 원하는 기능을 구현할 수 있으니까.