dma_handle 포인터와 cpu_addr 를 각각 관리하는 이유

 

  1. DMA 장치와 CPU 간의 메모리 구조의 차이: 일반적으로 DMA 장치는 메모리에 직접 접근하여 데이터를 전송합니다. 이 때 DMA 장치는 메모리 주소 공간을 CPU가 사용하는 것과 다르게 볼 수 있습니다. 예를 들어, 일부 시스템에서는 DMA 장치가 접근할 수 있는 주소 공간이 제한되어 있거나 물리적인 주소 공간이 특정한 형식을 따를 수 있습니다. 그러므로 DMA 장치가 접근하는 주소와 CPU가 접근하는 주소가 다를 수 있습니다.
  2. 캐시 일관성(Cache Coherency): 많은 시스템에서 CPU는 캐시를 사용하여 성능을 향상시킵니다. 그러나 DMA 장치는 이러한 캐시 구조에 직접적으로 접근할 수 없기 때문에, CPU가 쓴 데이터가 캐시에 존재하는 경우에도 DMA 장치에서 해당 데이터를 읽을 때 문제가 발생할 수 있습니다. 이를 해결하기 위해서는 DMA 전송 전에 캐시를 플러시하거나(invalidate) DMA 전송 후에 캐시를 재설정해야 할 수 있습니다. 이러한 캐시 일관성 문제를 해결하기 위해 DMA 할당 함수는 CPU가 접근하는 메모리 주소와 DMA 장치가 접근하는 메모리 주소를 따로 관리합니다. 이를 통해 DMA 전송 시에 캐시 일관성을 유지할 수 있습니다.

 

#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
typedef u64 dma_addr_t;
#else
typedef u32 dma_addr_t;
#endif
void *dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle,
        gfp_t flag, unsigned long attrs)
{
    const struct dma_map_ops *ops = get_dma_ops(dev);
    void *cpu_addr;

    WARN_ON_ONCE(!dev->coherent_dma_mask);

    if (dma_alloc_from_dev_coherent(dev, size, dma_handle, &cpu_addr))
        return cpu_addr;

    /* let the implementation decide on the zone to allocate from: */
    flag &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);

    if (dma_alloc_direct(dev, ops))
        cpu_addr = dma_direct_alloc(dev, size, dma_handle, flag, attrs);
    else if (ops->alloc)
        cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs);
    else
        return NULL;

    debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
    return cpu_addr;
}
EXPORT_SYMBOL(dma_alloc_attrs);

 

반응형

'Interface' 카테고리의 다른 글

Linux : target is busy during unmount  (0) 2024.04.05
USB | DWC3 Gadget initialization (UMS)  (0) 2024.03.21
USB | Quirks  (0) 2024.03.20

Check the process who is using the mounted path

fuser -cu mount_path

 

 

Kill the process

fuser -ck mount_path

반응형

'Interface' 카테고리의 다른 글

dma_handle & cpu_addr  (0) 2024.04.18
USB | DWC3 Gadget initialization (UMS)  (0) 2024.03.21
USB | Quirks  (0) 2024.03.20

from U-boot console

#> ums 0 mmc 0


// dwc3 init

set_state_simple op missing
UMS: LUN 0, dev 0, hwpart 0, sector 0x0, count 0x1d1f000
dwc3_alloc_event_buffers
dwc3_alloc_one_event_buffer
dwc3_core_init
dwc3_core_soft_reset
found 10 IN and 6 OUT endpoints
dwc3_alloc_scratch_buffers
dwc3_setup_scratch_buffers
dwc3_event_buffers_setup
Event buf 00000000eb5762c0 dma eb5762c0 length 256
dwc3_set_mode 2
dwc3_gadget_init
dwc3_uboot_init DONE
g_dnl_register g_dnl_driver.name = usb_dnl_ums
usb_composite_register
usb_gadget_register_driver
usb_gadget_probe_driver found
udc_bind_to_driver registering UDC driver [<NULL>]
registering UDC driver [<NULL>]
udc_bind_to_driver driver->speed 3
g_dnl_bind
g_dnl_bind gadget: 0x00000000eb579290 cdev: 0x00000000eb57c9e0
usb_gadget_connect


// D+ High for USB2.0

dwc3_gadget_run_stop is_on[1]
usb_gadget_udc_start
usb_gadget_connect
dwc3_gadget_run_stop is_on[1]

Connect USB line to a host 

// DWC3_LINK_STATE_U0 = 0x00, /* in HS, means ON */
// DWC3_LINK_STATE_U3 = 0x03, /* in HS, means SUSPEND */
// DWC3_LINK_STATE_SS_DIS = 0x04,
// DWC3_LINK_STATE_RX_DET = 0x05, /* in HS, means Early Suspend */

dwc3_gadget_linksts_change_interrupt LINK STATUS Change 0>0
dwc3_gadget_linksts_change_interrupt LINK STATUS Change 0>5
dwc3_gadget_linksts_change_interrupt LINK STATUS Change 5>3
dwc3_suspend_gadget
dwc3_gadget_interrupt RESET
dwc3_gadget_reset_interrupt
dwc3_stop_active_transfers
dwc3_clear_stall_all_ep
dwc3_gadget_interrupt CON DONE
dwc3_gadget_linksts_change_interrupt LINK STATUS Change 3>0
dwc3_gadget_linksts_change_interrupt LINK STATUS Change 0>5
dwc3_gadget_interrupt RESET
dwc3_gadget_reset_interrupt
dwc3_reset_gadget
dwc3_stop_active_transfers
dwc3_clear_stall_all_ep
dwc3_gadget_interrupt CON DONE
dwc3_gadget_linksts_change_interrupt LINK STATUS Change 5>0
dwc3_gadget_linksts_change_interrupt LINK STATUS Change 0>5
dwc3_gadget_interrupt RESET
dwc3_gadget_reset_interrupt
dwc3_reset_gadget
dwc3_stop_active_transfers
dwc3_clear_stall_all_ep
dwc3_gadget_interrupt CON DONE
dwc3_gadget_linksts_change_interrupt LINK STATUS Change 5>0
dwc3_gadget_linksts_change_interrupt LINK STATUS Change 0>5
dwc3_gadget_interrupt RESET
dwc3_gadget_reset_interrupt
dwc3_reset_gadget
dwc3_stop_active_transfers
dwc3_clear_stall_all_ep
dwc3_gadget_interrupt CON DONE
dwc3_gadget_linksts_change_interrupt LINK STATUS Change 5>0
dwc3_gadget_linksts_change_interrupt LINK STATUS Change 0>5
dwc3_gadget_interrupt RESET
dwc3_gadget_reset_interrupt
dwc3_reset_gadget
dwc3_stop_active_transfers
dwc3_clear_stall_all_ep
dwc3_gadget_interrupt CON DONE
dwc3_gadget_linksts_change_interrupt LINK STATUS Change 5>0
enable_endpoint
dwc3_gadget_ep_enable
enable_endpoint
dwc3_gadget_ep_enable

// Ubuntu Host detect the connection
// Check partition and transfer data

dwc3_endpoint_interrupt XFERNOTREADY
dwc3_endpoint_interrupt XFERCOMPLETE
dwc3_endpoint_interrupt XFERNOTREADY
dwc3_endpoint_interrupt XFERCOMPLETE
dwc3_endpoint_interrupt XFERCOMPLETE
..
dwc3_endpoint_interrupt XFERCOMPLETE
dwc3_endpoint_interrupt XFERCOMPLETE
dwc3_endpoint_interrupt XFERCOMPLETE

// Remove the USB cable from the host

dwc3_gadget_linksts_change_interrupt LINK STATUS Change 0>5
dwc3_gadget_linksts_change_interrupt LINK STATUS Change 5>3
dwc3_suspend_gadget
dwc3_gadget_interrupt DISCONNECT
dwc3_gadget_disconnect_interrupt
dwc3_gadget_linksts_change_interrupt LINK STATUS Change 3>4


// Disconnect UMS from Device side (D+ low)

CTRL+C - Operation aborted
unregistering UDC driver [<NULL>]
dwc3_gadget_run_stop is_on[0]
dwc3_gadget_run_stop is_on[0]
usb_gadget_udc_stop
unregistering gadget
dwc3_set_mode 2
dwc3_gadget_run
=>

반응형

'Interface' 카테고리의 다른 글

dma_handle & cpu_addr  (0) 2024.04.18
Linux : target is busy during unmount  (0) 2024.04.05
USB | Quirks  (0) 2024.03.20
Word    : quirk
Meaning : an unusual habit or part of someone's personality, or something that is strange and unexpected
Examples: You have to get used to other people's quirks and foibles.
          There is a quirk in the rules that allows you to invest money without paying tax.

 

Quirks는 디바스에서 설계되고 예상한 대로 동작하지 않는 경우를 고려하는 속성을 의미한다.
"Quirks" are attributes of a device that are considered to be noncompliant with expected operation.

 

Example of quirk setting from DWC3 core :

 * @disable_scramble_quirk: set if we enable the disable scramble quirk
 * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk
 * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk
 * @req_p1p2p3_quirk: set if we enable request p1p2p3 quirk
 * @del_p1p2p3_quirk: set if we enable delay p1p2p3 quirk
 * @del_phy_power_chg_quirk: set if we enable delay phy power change quirk
 * @lfps_filter_quirk: set if we enable LFPS filter quirk
 * @rx_detect_poll_quirk: set if we enable rx_detect to polling lfps quirk
 * @dis_u3_susphy_quirk: set if we disable usb3 suspend phy
 * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy
 * @dis_u1u2_quirk: set if we reject transition to U1 or U2 state
 * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk

 

 

 

반응형

'Interface' 카테고리의 다른 글

dma_handle & cpu_addr  (0) 2024.04.18
Linux : target is busy during unmount  (0) 2024.04.05
USB | DWC3 Gadget initialization (UMS)  (0) 2024.03.21

+ Recent posts