static int
mrvlsdio_init_module(void)
{
    int ret;

    ENTER();

    // generate /proc/ entry
    create_proc_read_entry("mrvlsdio",  // entry in "/proc/mrvlsdio"
                           0,   // file attributes
                           NULL,        // parent dir
                           mrvlsdio_read_procmem,       // name of function
                           NULL);       // client data

    printk("*** mrvlsdio ***\n");
    printk("*** multifunction API ***\n");
    printk("*** Built on %s %s ***\n", __DATE__, __TIME__);

                                                                                                                                                                                /*--- mmoser 6/21/2007 ---*/
    INIT_LIST_HEAD(&sd_dev_list);
    spin_lock_init(&sd_dev_list_lock);

    INIT_LIST_HEAD(&sd_client_list);
    spin_lock_init(&sd_client_list_lock);

 

    ret = register_chrdev(sdio_major, "mrvlsdio", &mrvlsdio_fops);
  
    if (ret < 0) {
        printk(KERN_WARNING "mrvlsdio: can't get major %d  ret=%d\n",
                  sdio_major, ret);
    } else {
        printk(KERN_DEBUG "mrvlsdio: major %d\n", ret);
    }
    if (sdio_major == 0)
        sdio_major = ret;       /* dynamic */

        /** from 2.4 kernel source:
  * pci_register_driver - register a new pci driver
  *
  * Adds the driver structure to the list of registered drivers
  * Returns the number of pci devices which were claimed by the driver
  * during registration.  The driver remains registered even if the
  * return value is zero.
  */
    ret = pci_register_driver(&mrvlsdio);
    printk(KERN_DEBUG "%s: pci_register_driver with %d\n", __FILE__, ret);

    LEAVE();
//      return (ret);
    return 0;
}

 

---------------------------------------------------------------------------------------------------------------------------------------- 

static int
woal_init_module(void)
{
    int ret = (int) MLAN_STATUS_SUCCESS;
    int i = 0;
    fw_name = "/lib/firmware/mrvl/sd8786.bin";
    ENTER();

    /* Replace default fw image name for specific drv_mode */
    if (fw_name) {
 printk("fw_name = %s\n", fw_name);
        for (i = 0; i < (sizeof(drv_mode_tbl) / sizeof(drv_mode_tbl[0])); i++) {
            if (drv_mode_tbl[i].drv_mode == drv_mode) {
                drv_mode_tbl[i].fw_name = fw_name;
                break;
            }
        }
    }
    printk("fw_name = %s\n", fw_name);

    /* Init mutex */
    init_MUTEX(&AddRemoveCardSem);

    /* Register with bus */
    ret = (int) woal_bus_register();
    printk("bus ret = %d\n", ret);
    LEAVE();
    return ret;
}

 

mlan_status
woal_bus_register(void)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;

    ENTER();
   
     /* SD Driver Registration */
       if (sd_driver_register(&sdio_wlan)) {
 printk("SD Driver Registration Failed \n");
        LEAVE();
        return MLAN_STATUS_FAILURE;
    }

    LEAVE();
    return ret;
}

 

int
sd_driver_register(sd_driver * drv) //장치를 찾는 부분
{
    struct list_head *pTmp;  //연계 리스트 구조체
    PSD_CLIENT pClientTmp;
    PSD_DEVICE_DATA pDevTmp;
    int fn_mask;
    int fn;
    printk("sd_driver_register!!\n");
    GET_IF_SEMA();

    ENTER();

    pClientTmp = (PSD_CLIENT) kmalloc(sizeof(SD_CLIENT), GFP_KERNEL);

    if (pClientTmp == NULL) {
        REL_IF_SEMA();
        LEAVE();
        return -ENOMEM;
    }
#ifdef SDIO_MEM_TRACE
    printk(">>> kmalloc(SD_CLIENT)\n");
#endif

    memset(pClientTmp, 0, sizeof(SD_CLIENT));

    pClientTmp->drv = drv;

    printk("head = %d\n", list_empty(&sd_dev_list));
    printk("sd_dev_list.next = %u\n", &sd_dev_list.next);

    printk("sd_dev_list.prev = %u\n", &sd_dev_list.prev);
    // Check whether there is a SDIO device available
    if (!list_empty(&sd_dev_list)) {
    printk("list is not empty!!\n");
        list_for_each(pTmp, &sd_dev_list) {
     printk("list_for_each(???)\n");
            pDevTmp = (PSD_DEVICE_DATA) pTmp;

            spin_lock_irqsave(&pDevTmp->sd_dev_lock,
                              pDevTmp->sd_dev_lock_flags);
            if ((fn_mask = sd_match_device(drv, pDevTmp)) > 0) {
                // Assign the client driver to the lowest supported function
                for (fn = 1; fn <= pDevTmp->number_of_functions; fn++) {
                    if ((fn_mask & (1 << fn)) != 0) {
                        break;
                    }
                }
                if (fn <=
                    MIN(pDevTmp->number_of_functions, MAX_SDIO_FUNCTIONS - 1)) {
                    if (pDevTmp->sd_dev[fn].drv == NULL) {
                        pDevTmp->sd_dev[fn].drv = drv;
                        pDevTmp->sd_dev[fn].supported_functions = fn_mask;
                        pDevTmp->sd_dev[fn].cisptr = &pDevTmp->cisptr[0];
                        pDevTmp->sd_dev[fn].sd_bus = pDevTmp;   // Backpointer
                                                                // to bus
                                                                // driver's
                                                                // device
                                                                // structure
                        pDevTmp->sd_dev[fn].dev = &pDevTmp->dev->dev;   // Generic
                                                                        // device
                                                                        // interface
                                                                        // for
                                                                        // hotplug

                        spin_unlock_irqrestore(&pDevTmp->sd_dev_lock,
                                               pDevTmp->sd_dev_lock_flags);
                        printk(KERN_DEBUG
                                  "%s: Driver registered: %s for functions 0x%2.02X\n",
                                  __FUNCTION__, pDevTmp->sd_dev[fn].drv->name,
                                  fn_mask);

                        if (pDevTmp->sd_dev[fn].drv->probe != NULL) {
                            pDevTmp->sd_dev[fn].probe_called = 1;
                            pDevTmp->sd_dev[fn].remove_called = 0;

                            printk(KERN_DEBUG
                                      "%s: call probe() handler on fn=%d\n",
                                      __FUNCTION__, fn);
                            REL_IF_SEMA();
                            call_client_probe(pDevTmp, fn);
                            GET_IF_SEMA();
                        } else {
                            // If we have no probe() handler at this point, we
                            // will never get one.
                            // This situation is considered a bug in the client
                            // driver !!!!
                            printk(KERN_DEBUG
                                      "%s@%d: no probe() handler installed for fn=%d! Revise client driver!!!\n",
                                      __FUNCTION__, __LINE__, fn);
                        }
                        break;
                    } else {
                        spin_unlock_irqrestore(&pDevTmp->sd_dev_lock,
                                               pDevTmp->sd_dev_lock_flags);
                        continue;
                    }
                }
            } else {
                spin_unlock_irqrestore(&pDevTmp->sd_dev_lock,
                                       pDevTmp->sd_dev_lock_flags);
                continue;
            }
 
        }
        printk(KERN_ERR
                  "%s: There are already drivers registered for all devices!\n",
                  __FUNCTION__);
    }
    // Add driver to global client list
    spin_lock_irqsave(&sd_client_list_lock, sd_client_list_lock_flags);
    list_add_tail((struct list_head *) pClientTmp, &sd_client_list);
    spin_unlock_irqrestore(&sd_client_list_lock, sd_client_list_lock_flags);

    REL_IF_SEMA();
    LEAVE();
    return 0;
}

 

위 소스는 디바이스 드라이버의 일부분입니다.

 

이 디바이스 드라이버는 io부분과 main부분이 모듈 형식으로 따로 나눠 져있는데요.

 

선으로 나눈 윗부분이 io이고 밑부분이 main입니다.

 

진행되는 순서대로 함수를 작성하였습니다.

 

제가 궁금한 부분은 io부분에서 sd_dev_list에 초기화를 시켜주고 장치를 검색하는데요.

 

main에 오게 되면 세번째 함수인 sd_driver_register에 가서 list_empty에서 비었있다고 나오고 빠져나와버립니다.

 

sd_dev_list가 어디서 정보를 가지고 오는지 궁금하구요.

 

디바이스 드라이버 소스를 봐도 sd_dev_list 를 따로 초기화 해주는 부분은 없구요.

 

모듈이 판매한 회사에도 물어봤는데 디바이스드라이버를 cpu에 맞게 수정하면 된다고 하는데.

 

정확히 어디를 손봐야 될지 궁금합니다.

 

고수님들 부탁드립니다. 제발.