www.pudn.com > 422.rar > setup.c
/* setup.c * Linux serial-bus device driver. * Written by wang song yue--bupt email:wsy5228@sina.com * This software is released under the GPL-License. * Version 0.1 28 october 2005 */ #include#if defined (CONFIG_MODVERSIONS) && !defined (MODVERSIONS) #define MODVERSIONS #endif #if defined (MODVERSIONS) #include #endif #include #include #include "../.support" #include "../include/main.h" #include "../include/setup.h" #include "../include/aim104.h" extern int s16c554_register(struct chipspecops_t *chipspecops); extern int aim104_register(struct hwspecops_t *hwspecops); int init_device_struct(int card); int init_hwspecops(int card); int init_chip_struct(int card); int init_obj_struct(int card, int chip); int init_chipspecops(int card, int chipnr); int add_mem_to_list(void *address_p) { struct mem_addr *mem_new; #ifdef DEBUG_MEM DEBUGMSG("add_mem_to_list %p, mem_head=%p\n",address_p, mem_head); return 0; #endif mem_new=(struct mem_addr *)kmalloc(sizeof(struct mem_addr),GFP_KERNEL); if (mem_new == NULL) { CANMSG("Memory list error.\n"); return -ENOMEM; } mem_new->next=mem_head; mem_new->address=address_p; mem_head=mem_new; return 0; } int del_mem_from_list(void *address_p) { struct mem_addr *mem_search=NULL; struct mem_addr *mem_delete=NULL; #ifdef DEBUG_MEM DEBUGMSG("del_mem_from_list %p, mem_head=%p\n", address_p, mem_head); return 0; #endif mem_search = mem_head; if (mem_head->address == address_p) { kfree(mem_head->address); mem_head=mem_head->next; kfree(mem_search); } else { while (mem_search->next->address != address_p) mem_search=mem_search->next; kfree(mem_search->next->address); mem_delete=mem_search->next; mem_search->next=mem_search->next->next; kfree(mem_delete); } return 0; } int del_mem_list(void) { struct mem_addr *mem_old; #ifdef DEBUG_MEM DEBUGMSG("del_mem_list, mem_head=%p\n", mem_head); return 0; #endif while (mem_head->next != NULL) { mem_old=mem_head; kfree(mem_old->address); mem_head=mem_old->next; kfree(mem_old); } return 0; } /* The function init_hw_struct is used to initialize the hardware structure. */ int init_hw_struct(void) { int i=0; hardware_p->nr_boards=0; while ( (hw[i] != NULL) & (i < MAX_HW_CARDS) ) { hardware_p->nr_boards++; if (init_device_struct(i)) { CANMSG("Error initializing candevice_t structures.\n"); return -ENODEV; } i++; } return 0; } /* The function init_device_struct is used to initialize a single device * structure. */ int init_device_struct(int card) { hardware_p->candevice[card]=(struct candevice_t *)kmalloc(sizeof(struct candevice_t),GFP_KERNEL); if (hardware_p->candevice[card]==NULL) return -ENOMEM; else if ( add_mem_to_list(hardware_p->candevice[card]) ) return -ENOMEM; candevices_p[card]=hardware_p->candevice[card]; hardware_p->candevice[card]->hwname=hw[card]; hardware_p->candevice[card]->io_addr=io[card]; hardware_p->candevice[card]->hwspecops=(struct hwspecops_t *)kmalloc(sizeof(struct hwspecops_t),GFP_KERNEL); if (hardware_p->candevice[card]->hwspecops==NULL) return -ENOMEM; else if ( add_mem_to_list(hardware_p->candevice[card]->hwspecops) ) return -ENOMEM; if (init_hwspecops(card)) return -ENODEV; if (candevices_p[card]->hwspecops->init_hw_data(card)) return -ENODEV; if (init_chip_struct(card)) return -ENODEV; return 0; } /* The function init_chip_struct is used to initialize all chip_t structures * on one hardware board. */ int init_chip_struct(int card) { static int irq_count=0; int i=0; /* Alocate and initialize the chip structures */ for (i=0; i nr_16c554_chips; i++) { candevices_p[card]->chip[i]=(struct chip_t *)kmalloc(sizeof(struct chip_t),GFP_KERNEL); if (candevices_p[card]->chip[i]==NULL) return -ENOMEM; else if ( add_mem_to_list(candevices_p[card]->chip[i]) ) return -ENOMEM; candevices_p[card]->chip[i]->chipspecops=(struct chipspecops_t *)kmalloc(sizeof(struct chipspecops_t),GFP_KERNEL); if (candevices_p[card]->chip[i]->chipspecops==NULL) return -ENOMEM; else if ( add_mem_to_list(candevices_p[card]->chip[i]->chipspecops) ) return -ENOMEM; chips_p[irq_count]=candevices_p[card]->chip[i]; candevices_p[card]->chip[i]->hostdevice=candevices_p[card]; candevices_p[card]->chip[i]->chip_irq=irq[irq_count]; candevices_p[card]->chip[i]->flags=0x0; candevices_p[card]->hwspecops->init_chip_data(card,i); if (init_chipspecops(card,i)) return -ENODEV; init_obj_struct(card, irq_count); irq_count++; } return 0; } int init_obj_struct(int card, int chip) { static int obj_count=0; int i=0,max_objects=0; // if (!strcmp(chips_p[chip]->chip_type,"i82527")) // max_objects=15; // else max_objects=1; for (i=0; i msgobj[i]=(struct msgobj_t *)kmalloc(sizeof(struct msgobj_t),GFP_KERNEL); if (chips_p[chip]->msgobj[i] == NULL) return -ENOMEM; else if ( add_mem_to_list(chips_p[chip]->msgobj[i]) ) return -ENOMEM; chips_p[chip]->msgobj[i]->fifo=(struct canfifo_t *)kmalloc(sizeof(struct canfifo_t),GFP_KERNEL); if (chips_p[chip]->msgobj[i]->fifo == NULL) return -ENOMEM; else if ( add_mem_to_list(chips_p[chip]->msgobj[i]->fifo) ) return -ENOMEM; if (minor[0] == -1) { objects_p[obj_count]=chips_p[chip]->msgobj[i]; objects_p[obj_count]->hostchip=chips_p[chip]; objects_p[obj_count]->object=i+1; objects_p[obj_count]->minor=obj_count; } else { objects_p[minor[chip]+i]=chips_p[chip]->msgobj[i]; objects_p[minor[chip]+i]->hostchip=chips_p[chip]; objects_p[minor[chip]+i]->object=i+1; objects_p[minor[chip]+i]->minor=minor[chip]+i; } chips_p[chip]->msgobj[i]->flags = 0x0; candevices_p[card]->hwspecops->init_obj_data(chip,i); obj_count++; } return 0; } int init_hwspecops(int card) { #ifdef AIM104 if (!strcmp(candevices_p[card]->hwname,"aim104")) { aim104_register(candevices_p[card]->hwspecops); } #endif return 0; } int init_chipspecops(int card, int chipnr) { if (!strcmp(candevices_p[card]->chip[chipnr]->chip_type,"16c554")) { s16c554_register(candevices_p[card]->chip[chipnr]->chipspecops); } return 0; }