loglevel = CTC_LOGLEVEL_DEFAULT; 
add_channel(struct ccw_device *cdev, enum channel_types type){	struct channel **c = &channels;	struct channel *ch;	DBF_TEXT(trace, 2, __FUNCTION__);	if ((ch =	     (struct channel *) kmalloc(sizeof (struct channel),					GFP_KERNEL)) == NULL) {		ctc_pr_warn("ctc: Out of memory in add_channel\n");		return -1;	}	memset(ch, 0, sizeof (struct channel));	if ((ch->ccw = (struct ccw1 *) kmalloc(8*sizeof(struct ccw1),					       GFP_KERNEL | GFP_DMA)) == NULL) {		kfree(ch);		ctc_pr_warn("ctc: Out of memory in add_channel\n");		return -1;	}	memset(ch->ccw, 0, 8*sizeof(struct ccw1));	// assure all flags and counters are reset	/**	 * "static" ccws are used in the following way:	 *	 * ccw[0..2] (Channel program for generic I/O):	 *           0: prepare	 *           1: read or write (depending on direction) with fixed	 *              buffer (idal allocated once when buffer is allocated)	 *           2: nop	 * ccw[3..5] (Channel program for direct write of packets)	 *           3: prepare	 *           4: write (idal allocated on every write).	 *           5: nop	 * ccw[6..7] (Channel program for initial channel setup):	 *           6: set extended mode	 *           7: nop	 *	 * ch->ccw[0..5] are initialized in ch_action_start because	 * the channel's direction is yet unknown here.	 */	ch->ccw[6].cmd_code = CCW_CMD_SET_EXTENDED;	ch->ccw[6].flags = CCW_FLAG_SLI;	ch->ccw[7].cmd_code = CCW_CMD_NOOP;	ch->ccw[7].flags = CCW_FLAG_SLI;	ch->cdev = cdev;	snprintf(ch->id, CTC_ID_SIZE, "ch-%s", cdev->dev.bus_id);	ch->type = type;	loglevel = CTC_LOGLEVEL_DEFAULT;	ch->fsm = init_fsm(ch->id, ch_state_names,			   ch_event_names, NR_CH_STATES, NR_CH_EVENTS,			   ch_fsm, CH_FSM_LEN, GFP_KERNEL);	if (ch->fsm == NULL) {		ctc_pr_warn("ctc: Could not create FSM in add_channel\n");		kfree(ch->ccw);		kfree(ch);		return -1;	}	fsm_newstate(ch->fsm, CH_STATE_IDLE);	if ((ch->irb = (struct irb *) kmalloc(sizeof (struct irb),					      GFP_KERNEL)) == NULL) {		ctc_pr_warn("ctc: Out of memory in add_channel\n");		kfree_fsm(ch->fsm);		kfree(ch->ccw);		kfree(ch);		return -1;	}	memset(ch->irb, 0, sizeof (struct irb));	while (*c && less_than((*c)->id, ch->id))		c = &(*c)->next;	if (*c && (!strncmp((*c)->id, ch->id, CTC_ID_SIZE))) {		ctc_pr_debug(			"ctc: add_channel: device %s already in list, "			"using old entry\n", (*c)->id);		kfree(ch->irb);		kfree_fsm(ch->fsm);		kfree(ch->ccw);		kfree(ch);		return 0;	}	fsm_settimer(ch->fsm, &ch->timer);	skb_queue_head_init(&ch->io_queue);	skb_queue_head_init(&ch->collect_queue);	ch->next = *c;	*c = ch;	return 0;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/7394c928c849fe2ea5c20b6d73cbe7f220810d94/ctcmain.c/buggy/drivers/s390/net/ctcmain.c