X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/2c5dbee366e95b46de0cb95cab23d2a94a13f184..d8365e7fd56ca15c05502848338017013e628a9d:/lincan/src/setup.c diff --git a/lincan/src/setup.c b/lincan/src/setup.c index acc7cac..72ef1a9 100644 --- a/lincan/src/setup.c +++ b/lincan/src/setup.c @@ -18,10 +18,10 @@ extern int sja1000_register(struct chipspecops_t *chipspecops); extern int sja1000p_register(struct chipspecops_t *chipspecops); extern int i82527_register(struct chipspecops_t *chipspecops); -int init_device_struct(int card); -int init_hwspecops(struct candevice_t *candev); -int init_chip_struct(struct candevice_t *candev); -int init_obj_struct(struct candevice_t *candev, struct chip_t *hostchip, int minorbase); +int init_hwspecops(struct candevice_t *candev, int *irqnum_p); +int init_device_struct(int card, int *chan_param_idx_p, int *irq_param_idx_p); +int init_chip_struct(struct candevice_t *candev, int chipnr, int irq, long baudrate); +int init_obj_struct(struct candevice_t *candev, struct chip_t *hostchip, int objnr); int init_chipspecops(struct candevice_t *candev, int chipnr); void *can_checked_malloc(size_t size) @@ -153,16 +153,64 @@ int can_base_addr_fixup(struct candevice_t *candev, unsigned long new_base) return 0; } + +int register_obj_struct(struct msgobj_t *obj, int minorbase) +{ + static int next_minor=0; + int i; + + if(minorbase>=0) + next_minor=minorbase; + if(next_minor>=MAX_TOT_MSGOBJS) + next_minor=0; + i=next_minor; + do{ + if(objects_p[i]==NULL){ + objects_p[i]=obj; + obj->minor=i; + next_minor=i+1; + return 0; + } + if(++i >= MAX_TOT_MSGOBJS) i=0; + }while(i!=next_minor); + obj->minor=-1; + return -1; +} + + +int register_chip_struct(struct chip_t *chip, int minorbase) +{ + static int next_chip_slot=0; + int i; + + if(next_chip_slot>=MAX_TOT_CHIPS) + next_chip_slot=0; + i=next_chip_slot; + do{ + if(chips_p[i]==NULL){ + chips_p[i]=chip; + + next_chip_slot=i+1; + return 0; + } + if(++i >= MAX_TOT_CHIPS) i=0; + }while(i!=next_chip_slot); + return -1; +} + + /* The function init_hw_struct is used to initialize the hardware structure. */ int init_hw_struct(void) { int i=0; + int irq_param_idx=0; + int chan_param_idx=0; hardware_p->nr_boards=0; while ( (hw[i] != NULL) & (i < MAX_HW_CARDS) ) { hardware_p->nr_boards++; - if (init_device_struct(i)) { + if (init_device_struct(i, &chan_param_idx, &irq_param_idx)) { CANMSG("Error initializing candevice_t structures.\n"); return -ENODEV; } @@ -175,10 +223,14 @@ int init_hw_struct(void) /* The function init_device_struct is used to initialize a single device * structure. */ -int init_device_struct(int card) +int init_device_struct(int card, int *chan_param_idx_p, int *irq_param_idx_p) { struct candevice_t *candev; int ret; + int irqnum; + int chipnr; + long bd; + int irqsig=-1; candev=(struct candevice_t *)can_checked_malloc(sizeof(struct candevice_t)); if (candev==NULL) @@ -201,14 +253,42 @@ int init_device_struct(int card) memset(candev->hwspecops, 0, sizeof(struct hwspecops_t)); - if (init_hwspecops(candev)) + if (init_hwspecops(candev, &irqnum)) goto error_nodev; if (candev->hwspecops->init_hw_data(candev)) goto error_nodev; - if ((ret=init_chip_struct(candev))) - goto error_chip; + /* Alocate and initialize the chip structures */ + for (chipnr=0; chipnr < candev->nr_all_chips; chipnr++) { + + if(chipnrnr_all_chips; chipnr++) { + int m=minor[*chan_param_idx_p+chipnr]; + struct chip_t *chip=candev->chip[chipnr]; + int objnr; + + register_chip_struct(chip, m); + + for (objnr=0; objnrmax_objects; objnr++) { + register_obj_struct(chip->msgobj[objnr], m); + if(m>=0) m++; + } + } + + *irq_param_idx_p += irqnum; + *chan_param_idx_p += candev->nr_all_chips; return 0; @@ -231,96 +311,84 @@ int init_device_struct(int card) /* The function init_chip_struct is used to initialize all chip_t structures * on one hardware board. */ -int init_chip_struct(struct candevice_t *candev) +int init_chip_struct(struct candevice_t *candev, int chipnr, int irq, long baudrate) { struct chip_t *chip; - static int irq_count=0; - int i=0; + int objnr; + int ret; - /* Alocate and initialize the chip structures */ - for (i=0; i < candev->nr_all_chips; i++) { - candev->chip[i]=(struct chip_t *)can_checked_malloc(sizeof(struct chip_t)); - if ((chip=candev->chip[i])==NULL) - return -ENOMEM; + candev->chip[chipnr]=(struct chip_t *)can_checked_malloc(sizeof(struct chip_t)); + if ((chip=candev->chip[chipnr])==NULL) + return -ENOMEM; - memset(chip, 0, sizeof(struct chip_t)); - - chip->write_register=candev->hwspecops->write_register; - chip->read_register=candev->hwspecops->read_register; + memset(chip, 0, sizeof(struct chip_t)); - chip->chipspecops=can_checked_malloc(sizeof(struct chipspecops_t)); - if (chip->chipspecops==NULL) - return -ENOMEM; - - chips_p[irq_count]=chip; - chip->chip_idx=i; - chip->hostdevice=candev; - chip->chip_irq=irq[irq_count]; - chip->baudrate=baudrate[irq_count]*1000; - if(!chip->baudrate) - chip->baudrate=baudrate[0]*1000; - chip->flags=0x0; - - candev->hwspecops->init_chip_data(candev,i); - - if (init_chipspecops(candev,i)) - return -ENODEV; - - init_obj_struct(candev, chip, minor[irq_count]); + chip->write_register=candev->hwspecops->write_register; + chip->read_register=candev->hwspecops->read_register; - irq_count++; - } + chip->chipspecops=can_checked_malloc(sizeof(struct chipspecops_t)); + if (chip->chipspecops==NULL) + return -ENOMEM; + + chip->chip_idx=chipnr; + chip->hostdevice=candev; + chip->chip_irq=irq; + chip->baudrate=baudrate; + chip->flags=0x0; + + candev->hwspecops->init_chip_data(candev,chipnr); + + if (init_chipspecops(candev,chipnr)) + return -ENODEV; + + for (objnr=0; objnrmax_objects; objnr++) { + ret=init_obj_struct(candev, chip, objnr); + if(ret<0) return ret; + } return 0; } -int init_obj_struct(struct candevice_t *candev, struct chip_t *hostchip, int minorbase) + +int init_obj_struct(struct candevice_t *candev, struct chip_t *hostchip, int objnr) { struct canque_ends_t *qends; - static int obj_count=0; - int i,max_objects; struct msgobj_t *obj; + int ret; - max_objects=hostchip->max_objects; - for (i=0; imsgobj[i]=obj; - if (obj == NULL) - return -ENOMEM; - - memset(obj, 0, sizeof(struct msgobj_t)); + obj=(struct msgobj_t *)can_checked_malloc(sizeof(struct msgobj_t)); + hostchip->msgobj[objnr]=obj; + if (obj == NULL) + return -ENOMEM; - atomic_set(&obj->obj_used,0); - INIT_LIST_HEAD(&obj->obj_users); - init_timer(&obj->tx_timeout); - - qends = (struct canque_ends_t *)can_checked_malloc(sizeof(struct canque_ends_t)); - if(qends == NULL) return -ENOMEM; - memset(qends, 0, sizeof(struct canque_ends_t)); - obj->hostchip=hostchip; - obj->object=i+1; - obj->qends=qends; - obj->tx_qedge=NULL; - obj->tx_slot=NULL; - obj->obj_flags = 0x0; - - canqueue_ends_init_chip(qends, hostchip, obj); - - if (minorbase == -1) minorbase=obj_count; - if ((minorbase >= 0) && (minorbase+iminor=minorbase+i; - } else obj->minor=-1; + memset(obj, 0, sizeof(struct msgobj_t)); + obj->minor=-1; - candev->hwspecops->init_obj_data(hostchip,i); + atomic_set(&obj->obj_used,0); + INIT_LIST_HEAD(&obj->obj_users); + init_timer(&obj->tx_timeout); - obj_count++; - } + qends = (struct canque_ends_t *)can_checked_malloc(sizeof(struct canque_ends_t)); + if(qends == NULL) return -ENOMEM; + memset(qends, 0, sizeof(struct canque_ends_t)); + obj->hostchip=hostchip; + obj->object=objnr+1; + obj->qends=qends; + obj->tx_qedge=NULL; + obj->tx_slot=NULL; + obj->obj_flags = 0x0; + + ret=canqueue_ends_init_chip(qends, hostchip, obj); + if(ret<0) return ret; + + ret=candev->hwspecops->init_obj_data(hostchip,objnr); + if(ret<0) return ret; + return 0; } -int init_hwspecops(struct candevice_t *candev) +int init_hwspecops(struct candevice_t *candev, int *irqnum_p) { const struct boardtype_t *brp; @@ -331,11 +399,14 @@ int init_hwspecops(struct candevice_t *candev) return -EINVAL; } + if(irqnum_p) + *irqnum_p=brp->irqnum; brp->board_register(candev->hwspecops); return 0; } + int init_chipspecops(struct candevice_t *candev, int chipnr) { if (!strcmp(candev->chip[chipnr]->chip_type,"i82527")) {