도와주세요!!
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에 맞게 수정하면 된다고 하는데.
정확히 어디를 손봐야 될지 궁금합니다.
고수님들 부탁드립니다. 제발.