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

📄 cpqphp_ctrl.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
		return(2);}/** * bridge_slot_remove - Removes a node from the linked list of slots. * @bridge: bridge to remove * * Returns 0 if successful, !0 otherwise. */static int bridge_slot_remove(struct pci_func *bridge){	u8 subordinateBus, secondaryBus;	u8 tempBus;	struct pci_func *next;	if (bridge == NULL)		return(1);	secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;	subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;	for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {		next = cpqhp_slot_list[tempBus];		while (!slot_remove(next)) {			next = cpqhp_slot_list[tempBus];		}	}	next = cpqhp_slot_list[bridge->bus];	if (next == NULL) {		return(1);	}	if (next == bridge) {		cpqhp_slot_list[bridge->bus] = bridge->next;		kfree(bridge);		return(0);	}	while ((next->next != bridge) && (next->next != NULL)) {		next = next->next;	}	if (next->next == bridge) {		next->next = bridge->next;		kfree(bridge);		return(0);	} else		return(2);}/** * cpqhp_slot_find - Looks for a node by bus, and device, multiple functions accessed * @bus: bus to find * @device: device to find * @index: is 0 for first function found, 1 for the second... * * Returns pointer to the node if successful, %NULL otherwise. */struct pci_func *cpqhp_slot_find(u8 bus, u8 device, u8 index){	int found = -1;	struct pci_func *func;	func = cpqhp_slot_list[bus];	if ((func == NULL) || ((func->device == device) && (index == 0)))		return(func);	if (func->device == device)		found++;	while (func->next != NULL) {		func = func->next;		if (func->device == device)			found++;		if (found == index)			return(func);	}	return(NULL);}// DJZ: I don't think is_bridge will work as is.//FIXMEstatic int is_bridge(struct pci_func * func){	// Check the header type	if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)		return 1;	else		return 0;}/* the following routines constitute the bulk of the    hotplug controller logic *//** * board_replaced - Called after a board has been replaced in the system. * * This is only used if we don't have resources for hot add * Turns power on for the board * Checks to see if board is the same * If board is same, reconfigures it * If board isn't same, turns it back off. * */static u32 board_replaced(struct pci_func * func, struct controller * ctrl){	u8 hp_slot;	u8 temp_byte;	u32 index;	u32 rc = 0;	u32 src = 8;	hp_slot = func->device - ctrl->slot_device_offset;	if (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)) {		//*********************************		// The switch is open.		//*********************************		rc = INTERLOCK_OPEN;	} else if (is_slot_enabled (ctrl, hp_slot)) {		//*********************************		// The board is already on		//*********************************		rc = CARD_FUNCTIONING;	} else {		if (ctrl->speed == 1) {			// Wait for exclusive access to hardware			down(&ctrl->crit_sect);			// turn on board without attaching to the bus			enable_slot_power (ctrl, hp_slot);			set_SOGO(ctrl);			// Wait for SOBS to be unset			wait_for_ctrl_irq (ctrl);			// Change bits in slot power register to force another shift out			// NOTE: this is to work around the timer bug			temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);			writeb(0x00, ctrl->hpc_reg + SLOT_POWER);			writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);			set_SOGO(ctrl);			// Wait for SOBS to be unset			wait_for_ctrl_irq (ctrl);			if (!(readl(ctrl->hpc_reg + NON_INT_INPUT) & (0x01 << hp_slot))) {				rc = WRONG_BUS_FREQUENCY;			}			// turn off board without attaching to the bus			disable_slot_power (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);			if (rc)				return(rc);		}		// Wait for exclusive access to hardware		down(&ctrl->crit_sect);		slot_enable (ctrl, hp_slot);		green_LED_blink (ctrl, hp_slot);		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);		// Wait for ~1 second because of hot plug spec		long_delay(1*HZ);		// Check for a power fault		if (func->status == 0xFF) {			// power fault occurred, but it was benign			rc = POWER_FAILURE;			func->status = 0;		} else			rc = cpqhp_valid_replace(ctrl, func);		if (!rc) {			// It must be the same board			rc = cpqhp_configure_board(ctrl, func);			if (rc || src) {				// If configuration fails, turn it off				// Get slot won't work for devices behind bridges, but				// in this case it will always be called for the "base"				// bus/dev/func of an adapter.				// Wait for exclusive access to hardware				down(&ctrl->crit_sect);				amber_LED_on (ctrl, hp_slot);				green_LED_off (ctrl, hp_slot);				slot_disable (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);				if (rc)					return(rc);				else					return(1);			}			func->status = 0;			func->switch_save = 0x10;			index = 1;			while (((func = cpqhp_slot_find(func->bus, func->device, index)) != NULL) && !rc) {				rc |= cpqhp_configure_board(ctrl, func);				index++;			}			if (rc) {				// If configuration fails, turn it off				// Get slot won't work for devices behind bridges, but				// in this case it will always be called for the "base"				// bus/dev/func of an adapter.				// Wait for exclusive access to hardware				down(&ctrl->crit_sect);				amber_LED_on (ctrl, hp_slot);				green_LED_off (ctrl, hp_slot);				slot_disable (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);				return(rc);			}			// Done configuring so turn LED on full time			// Wait for exclusive access to hardware			down(&ctrl->crit_sect);			green_LED_on (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);			rc = 0;		} else {			// Something is wrong			// Get slot won't work for devices behind bridges, but			// in this case it will always be called for the "base"			// bus/dev/func of an adapter.			// Wait for exclusive access to hardware			down(&ctrl->crit_sect);			amber_LED_on (ctrl, hp_slot);			green_LED_off (ctrl, hp_slot);			slot_disable (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);		}	}	return(rc);}/** * board_added - Called after a board has been added to the system. * * Turns power on for the board * Configures board * */static u32 board_added(struct pci_func * func, struct controller * ctrl){	u8 hp_slot;	u8 temp_byte;	int index;	u32 temp_register = 0xFFFFFFFF;	u32 rc = 0;	struct pci_func *new_slot = NULL;	struct slot *p_slot;	struct resource_lists res_lists;	hp_slot = func->device - ctrl->slot_device_offset;	dbg(__FUNCTION__": func->device, slot_offset, hp_slot = %d, %d ,%d\n",	    func->device, ctrl->slot_device_offset, hp_slot);	if (ctrl->speed == 1) {		// Wait for exclusive access to hardware		down(&ctrl->crit_sect);		// turn on board without attaching to the bus		enable_slot_power (ctrl, hp_slot);		set_SOGO(ctrl);		// Wait for SOBS to be unset		wait_for_ctrl_irq (ctrl);		// Change bits in slot power register to force another shift out		// NOTE: this is to work around the timer bug		temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);		writeb(0x00, ctrl->hpc_reg + SLOT_POWER);		writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);		set_SOGO(ctrl);		// Wait for SOBS to be unset		wait_for_ctrl_irq (ctrl);		if (!(readl(ctrl->hpc_reg + NON_INT_INPUT) & (0x01 << hp_slot))) {			rc = WRONG_BUS_FREQUENCY;		}		// turn off board without attaching to the bus		disable_slot_power (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);		if (rc)			return(rc);	}	p_slot = find_slot(ctrl, hp_slot + ctrl->slot_device_offset);	// turn on board and blink green LED	// Wait for exclusive access to hardware	dbg(__FUNCTION__": before down\n");	down(&ctrl->crit_sect);	dbg(__FUNCTION__": after down\n");	dbg(__FUNCTION__": before slot_enable\n");	slot_enable (ctrl, hp_slot);	dbg(__FUNCTION__": before green_LED_blink\n");	green_LED_blink (ctrl, hp_slot);	dbg(__FUNCTION__": before amber_LED_blink\n");	amber_LED_off (ctrl, hp_slot);	dbg(__FUNCTION__": before set_SOGO\n");	set_SOGO(ctrl);	// Wait for SOBS to be unset	dbg(__FUNCTION__": before wait_for_ctrl_irq\n");	wait_for_ctrl_irq (ctrl);	dbg(__FUNCTION__": after wait_for_ctrl_irq\n");	// Done with exclusive hardware access	dbg(__FUNCTION__": before up\n");	up(&ctrl->crit_sect);	dbg(__FUNCTION__": after up\n");	// Wait for ~1 second because of hot plug spec	dbg(__FUNCTION__": before long_delay\n");	long_delay(1*HZ);	dbg(__FUNCTION__": after long_delay\n");	dbg(__FUNCTION__": func status = %x\n", func->status);	// Check for a power fault	if (func->status == 0xFF) {		// power fault occurred, but it was benign		temp_register = 0xFFFFFFFF;		dbg(__FUNCTION__": temp register set to %x by power fault\n", temp_register);		rc = POWER_FAILURE;		func->status = 0;	} else {		// Get vendor/device ID u32		rc = pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_VENDOR_ID, &temp_register);		dbg(__FUNCTION__": pci_read_config_dword returns %d\n", rc);		dbg(__FUNCTION__": temp_register is %x\n", temp_register);		if (rc != 0) {			// Something's wrong here			temp_register = 0xFFFFFFFF;			dbg(__FUNCTION__": temp register set to %x by error\n", temp_register);		}		// Preset return code.  It will be changed later if things go okay.		rc = NO_ADAPTER_PRESENT;	}	// All F's is an empty slot or an invalid board	if (temp_register != 0xFFFFFFFF) {	  // Check for a board in the slot		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;		res_lists.irqs = NULL;		rc = configure_new_device(ctrl, func, 0, &res_lists);		dbg(__FUNCTION__": back from configure_new_device\n");		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 (rc) {			// Wait for exclusive access to hardware			down(&ctrl->crit_sect);			amber_LED_on (ctrl, hp_slot);			green_LED_off (ctrl, hp_slot);			slot_disable (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);			return(rc);		} else {			cpqhp_save_slot_config(ctrl, func);		}		func->status = 0;		func->switch_save = 0x10;		func->is_a_board = 0x01;		//next, we will instantiate the linux pci_dev structures (with appropriate driver notification, if already present)		dbg(__FUNCTION__": configure linux pci_dev structure\n");		index = 0;		do {			new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++);			if (new_slot && !new_slot->pci_dev) {				cpqhp_configure_device(ctrl, new_slot);			}		} while (new_slot);		// Wait for exclusive access to hardware		down(&ctrl->crit_sect);		green_LED_on (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);	} else {		// Wait for exclusive access to hardware		down(&ctrl->crit_sect);		amber_LED_on (ctrl, hp_slot);		green_LED_off (ctrl, hp_slot);		slot_disable (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);		return(rc);	}	return 0;}

⌨️ 快捷键说明

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