⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpqphp_ctrl.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
/** * remove_board - Turns off slot and LED's * */static u32 remove_board(struct pci_func * func, u32 replace_flag, struct controller * ctrl){	int index;	u8 skip = 0;	u8 device;	u8 hp_slot;	u8 temp_byte;	u32 rc;	struct resource_lists res_lists;	struct pci_func *temp_func;	if (func == NULL)		return(1);	if (cpqhp_unconfigure_device(func))		return(1);	device = func->device;	hp_slot = func->device - ctrl->slot_device_offset;	dbg("In "__FUNCTION__", hp_slot = %d\n", hp_slot);	// When we get here, it is safe to change base Address Registers.	// We will attempt to save the base Address Register Lengths	if (replace_flag || !ctrl->add_support)		rc = cpqhp_save_base_addr_length(ctrl, func);	else if (!func->bus_head && !func->mem_head &&		 !func->p_mem_head && !func->io_head) {		// Here we check to see if we've saved any of the board's		// resources already.  If so, we'll skip the attempt to		// determine what's being used.		index = 0;		temp_func = cpqhp_slot_find(func->bus, func->device, index++);		while (temp_func) {			if (temp_func->bus_head || temp_func->mem_head			    || temp_func->p_mem_head || temp_func->io_head) {				skip = 1;				break;			}			temp_func = cpqhp_slot_find(temp_func->bus, temp_func->device, index++);		}		if (!skip)			rc = cpqhp_save_used_resources(ctrl, func);	}	// Change status to shutdown	if (func->is_a_board)		func->status = 0x01;	func->configured = 0;	// Wait for exclusive access to hardware	down(&ctrl->crit_sect);	green_LED_off (ctrl, hp_slot);	slot_disable (ctrl, hp_slot);	set_SOGO(ctrl);	// turn off SERR for slot	temp_byte = readb(ctrl->hpc_reg + SLOT_SERR);	temp_byte &= ~(0x01 << hp_slot);	writeb(temp_byte, ctrl->hpc_reg + SLOT_SERR);	// Wait for SOBS to be unset	wait_for_ctrl_irq (ctrl);	// Done with exclusive hardware access	up(&ctrl->crit_sect);	if (!replace_flag && ctrl->add_support) {		while (func) {			res_lists.io_head = ctrl->io_head;			res_lists.mem_head = ctrl->mem_head;			res_lists.p_mem_head = ctrl->p_mem_head;			res_lists.bus_head = ctrl->bus_head;			cpqhp_return_board_resources(func, &res_lists);			ctrl->io_head = res_lists.io_head;			ctrl->mem_head = res_lists.mem_head;			ctrl->p_mem_head = res_lists.p_mem_head;			ctrl->bus_head = res_lists.bus_head;			cpqhp_resource_sort_and_combine(&(ctrl->mem_head));			cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));			cpqhp_resource_sort_and_combine(&(ctrl->io_head));			cpqhp_resource_sort_and_combine(&(ctrl->bus_head));			if (is_bridge(func)) {				bridge_slot_remove(func);			} else				slot_remove(func);			func = cpqhp_slot_find(ctrl->bus, device, 0);		}		// Setup slot structure with entry for empty slot		func = cpqhp_slot_create(ctrl->bus);		if (func == NULL) {			// Out of memory			return(1);		}		func->bus = ctrl->bus;		func->device = device;		func->function = 0;		func->configured = 0;		func->switch_save = 0x10;		func->is_a_board = 0;		func->p_task_event = NULL;	}	return 0;}static void pushbutton_helper_thread (unsigned long data){	pushbutton_pending = data;	up(&event_semaphore);}// this is the main worker threadstatic int event_thread(void* data){	struct controller *ctrl;	lock_kernel();	daemonize();		//  New name	strcpy(current->comm, "phpd_event");		unlock_kernel();	while (1) {		dbg("!!!!event_thread sleeping\n");		down_interruptible (&event_semaphore);		dbg("event_thread woken finished = %d\n", event_finished);		if (event_finished) break;		/* Do stuff here */		if (pushbutton_pending)			cpqhp_pushbutton_thread(pushbutton_pending);		else			for (ctrl = cpqhp_ctrl_list; ctrl; ctrl=ctrl->next)				interrupt_event_handler(ctrl);	}	dbg("event_thread signals exit\n");	up(&event_exit);	return 0;}int cpqhp_event_start_thread (void){	int pid;	/* initialize our semaphores */	init_MUTEX(&delay_sem);	init_MUTEX_LOCKED(&event_semaphore);	init_MUTEX_LOCKED(&event_exit);	event_finished=0;	pid = kernel_thread(event_thread, 0, 0);	if (pid < 0) {		err ("Can't start up our event thread\n");		return -1;	}	dbg("Our event thread pid = %d\n", pid);	return 0;}void cpqhp_event_stop_thread (void){	event_finished = 1;	dbg("event_thread finish command given\n");	up(&event_semaphore);	dbg("wait for event_thread to exit\n");	down(&event_exit);}static int update_slot_info (struct controller *ctrl, struct slot *slot){	struct hotplug_slot_info *info;	char buffer[SLOT_NAME_SIZE];	int result;	info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);	if (!info)		return -ENOMEM;	make_slot_name (&buffer[0], SLOT_NAME_SIZE, slot);	info->power_status = get_slot_enabled(ctrl, slot);	info->attention_status = cpq_get_attention_status(ctrl, slot);	info->latch_status = cpq_get_latch_status(ctrl, slot);	info->adapter_status = get_presence_status(ctrl, slot);	result = pci_hp_change_slot_info(buffer, info);	kfree (info);	return result;}static void interrupt_event_handler(struct controller *ctrl){	int loop = 0;	int change = 1;	struct pci_func *func;	u8 hp_slot;	struct slot *p_slot;	while (change) {		change = 0;		for (loop = 0; loop < 10; loop++) {			//dbg("loop %d\n", loop);			if (ctrl->event_queue[loop].event_type != 0) {				hp_slot = ctrl->event_queue[loop].hp_slot;				func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);				p_slot = find_slot(ctrl, hp_slot + ctrl->slot_device_offset);				dbg("hp_slot %d, func %p, p_slot %p\n",				    hp_slot, func, p_slot);				if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) {					dbg("button pressed\n");				} else if (ctrl->event_queue[loop].event_type == 					   INT_BUTTON_CANCEL) {					dbg("button cancel\n");					del_timer(&p_slot->task_event);					// Wait for exclusive access to hardware					down(&ctrl->crit_sect);					if (p_slot->state == BLINKINGOFF_STATE) {						// slot is on						// turn on green LED						dbg("turn on green LED\n");						green_LED_on (ctrl, hp_slot);					} else if (p_slot->state == BLINKINGON_STATE) {						// slot is off						// turn off green LED						dbg("turn off green LED\n");						green_LED_off (ctrl, hp_slot);					}					info(msg_button_cancel, p_slot->number);					p_slot->state = STATIC_STATE;					amber_LED_off (ctrl, hp_slot);					set_SOGO(ctrl);					// Wait for SOBS to be unset					wait_for_ctrl_irq (ctrl);					// Done with exclusive hardware access					up(&ctrl->crit_sect);				}				// ***********button Released (No action on press...)				else if (ctrl->event_queue[loop].event_type == INT_BUTTON_RELEASE) {					dbg("button release\n");					if (is_slot_enabled (ctrl, hp_slot)) {						// slot is on						dbg("slot is on\n");						p_slot->state = BLINKINGOFF_STATE;						info(msg_button_off, p_slot->number);					} else {						// slot is off						dbg("slot is off\n");						p_slot->state = BLINKINGON_STATE;						info(msg_button_on, p_slot->number);					}					// Wait for exclusive access to hardware					down(&ctrl->crit_sect);					dbg("blink green LED and turn off amber\n");					amber_LED_off (ctrl, hp_slot);					green_LED_blink (ctrl, hp_slot);					set_SOGO(ctrl);					// Wait for SOBS to be unset					wait_for_ctrl_irq (ctrl);					// Done with exclusive hardware access					up(&ctrl->crit_sect);					init_timer(&p_slot->task_event);					p_slot->hp_slot = hp_slot;					p_slot->ctrl = ctrl;//					p_slot->physical_slot = physical_slot;					p_slot->task_event.expires = jiffies + 5 * HZ;   // 5 second delay					p_slot->task_event.function = pushbutton_helper_thread;					p_slot->task_event.data = (u32) p_slot;					dbg("add_timer p_slot = %p\n", p_slot);					add_timer(&p_slot->task_event);				}				// ***********POWER FAULT				else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {					dbg("power fault\n");				} else {					/* refresh notification */					if (p_slot)						update_slot_info(ctrl, p_slot);				}				ctrl->event_queue[loop].event_type = 0;				change = 1;			}		}		// End of FOR loop	}	return;}/** * cpqhp_pushbutton_thread * * Scheduled procedure to handle blocking stuff for the pushbuttons * Handles all pending events and exits. * */void cpqhp_pushbutton_thread (unsigned long slot){	u8 hp_slot;	u8 device;	struct pci_func *func;	struct slot *p_slot = (struct slot *) slot;	struct controller *ctrl = (struct controller *) p_slot->ctrl;	pushbutton_pending = 0;	hp_slot = p_slot->hp_slot;	device = p_slot->device;	if (is_slot_enabled (ctrl, hp_slot)) {		p_slot->state = POWEROFF_STATE;		// power Down board		func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);		dbg("In power_down_board, func = %p, ctrl = %p\n", func, ctrl);		if (!func) {			dbg("Error! func NULL in "__FUNCTION__"\n");			return ;		}		if (func != NULL && ctrl != NULL) {			if (cpqhp_process_SS(ctrl, func) != 0) {				amber_LED_on (ctrl, hp_slot);				green_LED_on (ctrl, hp_slot);								set_SOGO(ctrl);				// Wait for SOBS to be unset				wait_for_ctrl_irq (ctrl);			}		}		p_slot->state = STATIC_STATE;	} else {		p_slot->state = POWERON_STATE;		// slot is off		func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);		dbg("In add_board, func = %p, ctrl = %p\n", func, ctrl);		if (!func) {			dbg("Error! func NULL in "__FUNCTION__"\n");			return ;		}		if (func != NULL && ctrl != NULL) {			if (cpqhp_process_SI(ctrl, func) != 0) {				amber_LED_on (ctrl, hp_slot);				green_LED_off (ctrl, hp_slot);								set_SOGO(ctrl);				// Wait for SOBS to be unset				wait_for_ctrl_irq (ctrl);			}		}		p_slot->state = STATIC_STATE;	}	return;}int cpqhp_process_SI (struct controller *ctrl, struct pci_func *func){	u8 device, hp_slot;	u16 temp_word;	u32 tempdword;	int rc;	struct slot* p_slot;	int physical_slot = 0;	if (!ctrl)		return(1);	tempdword = 0;	device = func->device;	hp_slot = device - ctrl->slot_device_offset;	p_slot = find_slot(ctrl, device);	if (p_slot) {		physical_slot = p_slot->number;	}	// Check to see if the interlock is closed	tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);	if (tempdword & (0x01 << hp_slot)) {		return(1);	}	if (func->is_a_board) {		rc = board_replaced(func, ctrl);	} else {		// add board		slot_remove(func);		func = cpqhp_slot_create(ctrl->bus);		if (func == NULL) {			return(1);		}		func->bus = ctrl->bus;		func->device = device;		func->function = 0;		func->configured = 0;		func->is_a_board = 1;		// We have to save the presence info for these slots		temp_word = ctrl->ctrl_int_comp >> 16;		func->presence_save = (temp_word >> hp_slot) & 0x01;		func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;		if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {			func->switch_save = 0;		} else {			func->switch_save = 0x10;		}		rc = board_added(func, ctrl);		if (rc) {			if (is_bridge(func)) {				bridge_slot_remove(func);			} else				slot_remove(func);			// Setup slot structure with entry for empty slot			func = cpqhp_slot_create(ctrl->bus);			if (func == NULL) {				// Out of memory				return(1);			}			func->bus = ctrl->bus;			func->device = device;			func->function = 0;			func->configured = 0;			func->is_a_board = 0;			// We have to save the presence info for these slots			temp_word = ctrl->ctrl_int_comp >> 16;			func->presence_save = (temp_word >> hp_slot) & 0x01;			func->presence_save |=			(temp_word >> (hp_slot + 7)) & 0x02;			if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {				func->switch_save = 0;			} else {				func->switch_save = 0x10;			}		}	}	if (rc) {		dbg(__FUNCTION__": rc = %d\n", rc);	}	if (p_slot)		update_slot_info(ctrl, p_slot);	return rc;}int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func){	u8 device, class_code, header_type, BCR;	u8 index = 0;	u8 replace_flag;	u32 rc = 0;	struct slot* p_slot;	int physical_slot=0;	device = func->device; 	func = cpqhp_slot_find(ctrl->bus, device, index++);	p_slot = find_slot(ctrl, device);	if (p_slot) {		physical_slot = p_slot->number;	}	// Make sure there are no video controllers here	while (func && !rc) {		// Check the Class Code		rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0B, &class_code);		if (rc)			return rc;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -