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

📄 ibmphp_core.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (flag)		ibmphp_lock_operations ();	if (hotplug_slot && value) {		pslot = (struct slot *) hotplug_slot->private;		if (pslot) {			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));			rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, &(myslot.status));			if (!(SLOT_LATCH (myslot.status)) && (SLOT_PRESENT (myslot.status))) {				rc = ibmphp_hpc_readslot(pslot, READ_EXTSLOTSTATUS, &(myslot.ext_status));				if (!rc)					*value = SLOT_SPEED (myslot.ext_status);			} else				*value = MAX_ADAPTER_NONE;                }	}	if (flag)		ibmphp_unlock_operations ();	debug("get_max_adapter_speed_1 - Exit rc[%d] value[%x]\n", rc, *value);	return rc;}static int get_bus_name (struct hotplug_slot *hotplug_slot, char * value){	int rc = -ENODEV;	struct slot *pslot = NULL;	debug ("get_bus_name - Entry hotplug_slot[%lx]\n", (ulong)hotplug_slot);	ibmphp_lock_operations ();	if (hotplug_slot) {		pslot = (struct slot *) hotplug_slot->private;		if (pslot) {			rc = 0;			snprintf (value, 100, "Bus %x", pslot->bus);		}	} else		rc = -ENODEV;	ibmphp_unlock_operations ();	debug ("get_bus_name - Exit rc[%d] value[%x]\n", rc, *value);	return rc;}*//******************************************************************************* * This routine will initialize the ops data structure used in the validate * function. It will also power off empty slots that are powered on since BIOS * leaves those on, albeit disconnected ******************************************************************************/static int __init init_ops (void){	struct slot *slot_cur;	struct list_head *tmp;	int retval;	int rc;	list_for_each (tmp, &ibmphp_slot_head) {		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);		if (!slot_cur)			return -ENODEV;		debug ("BEFORE GETTING SLOT STATUS, slot # %x\n", slot_cur->number);		if (slot_cur->ctrl->revision == 0xFF) 			if (get_ctrl_revision (slot_cur, &slot_cur->ctrl->revision))				return -1;		if (slot_cur->bus_on->current_speed == 0xFF) 			if (get_cur_bus_info (&slot_cur)) 				return -1;		if (slot_cur->ctrl->options == 0xFF)			if (get_hpc_options (slot_cur, &slot_cur->ctrl->options))				return -1;		retval = slot_update (&slot_cur);		if (retval)			return retval;		debug ("status = %x\n", slot_cur->status);		debug ("ext_status = %x\n", slot_cur->ext_status);		debug ("SLOT_POWER = %x\n", SLOT_POWER (slot_cur->status));		debug ("SLOT_PRESENT = %x\n", SLOT_PRESENT (slot_cur->status));		debug ("SLOT_LATCH = %x\n", SLOT_LATCH (slot_cur->status));		if ((SLOT_PWRGD (slot_cur->status)) && 		    !(SLOT_PRESENT (slot_cur->status)) && 		    !(SLOT_LATCH (slot_cur->status))) {			debug ("BEFORE POWER OFF COMMAND\n");				rc = power_off (slot_cur);				if (rc)					return rc;	/*		retval = slot_update (&slot_cur);	 *		if (retval)	 *			return retval;	 *		ibmphp_update_slot_info (slot_cur);	 */		}	}	init_flag = 0;	return 0;}/* This operation will check whether the slot is within the bounds and * the operation is valid to perform on that slot * Parameters: slot, operation * Returns: 0 or error codes */static int validate (struct slot *slot_cur, int opn){	int number;	int retval;	if (!slot_cur)		return -ENODEV;	number = slot_cur->number;	if ((number > max_slots) || (number < 0))		return -EBADSLT;	debug ("slot_number in validate is %d\n", slot_cur->number);	retval = slot_update (&slot_cur);	if (retval)		return retval;	switch (opn) {		case ENABLE:			if (!(SLOT_PWRGD (slot_cur->status)) && 			     (SLOT_PRESENT (slot_cur->status)) && 			     !(SLOT_LATCH (slot_cur->status)))				return 0;			break;		case DISABLE:			if ((SLOT_PWRGD (slot_cur->status)) && 			    (SLOT_PRESENT (slot_cur->status)) &&			    !(SLOT_LATCH (slot_cur->status)))				return 0;			break;		default:			break;	}	err ("validate failed....\n");	return -EINVAL;}/******************************************************************************** * This routine is for updating the data structures in the hotplug core * Parameters: struct slot * Returns: 0 or error *******************************************************************************/int ibmphp_update_slot_info (struct slot *slot_cur){	struct hotplug_slot_info *info;	int rc;	u8 bus_speed;	u8 mode;	info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);	if (!info) {		err ("out of system memory\n");		return -ENOMEM;	}        	info->power_status = SLOT_PWRGD (slot_cur->status);	info->attention_status = SLOT_ATTN (slot_cur->status, slot_cur->ext_status);	info->latch_status = SLOT_LATCH (slot_cur->status);        if (!SLOT_PRESENT (slot_cur->status)) {                info->adapter_status = 0;//		info->max_adapter_speed_status = MAX_ADAPTER_NONE;	} else {                info->adapter_status = 1;//		get_max_adapter_speed_1 (slot_cur->hotplug_slot, &info->max_adapter_speed_status, 0);	}	bus_speed = slot_cur->bus_on->current_speed;	mode = slot_cur->bus_on->current_bus_mode;	switch (bus_speed) {	case BUS_SPEED_33:		break;	case BUS_SPEED_66:		if (mode == BUS_MODE_PCIX) 			bus_speed += 0x01;		else if (mode == BUS_MODE_PCI)			;		else			bus_speed = PCI_SPEED_UNKNOWN;		break;	case BUS_SPEED_100:	case BUS_SPEED_133:		bus_speed += 0x01;		break;	default:		bus_speed = PCI_SPEED_UNKNOWN;	}	info->cur_bus_speed = bus_speed;	info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;	// To do: bus_names 		rc = pci_hp_change_slot_info (slot_cur->hotplug_slot, info);	kfree (info);	return rc;}/****************************************************************************** * This function will return the pci_func, given bus and devfunc, or NULL.  It * is called from visit routines ******************************************************************************/static struct pci_func *ibm_slot_find (u8 busno, u8 device, u8 function){	struct pci_func *func_cur;	struct slot *slot_cur;	struct list_head * tmp;	list_for_each (tmp, &ibmphp_slot_head) {		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);		if (slot_cur->func) {			func_cur = slot_cur->func;			while (func_cur) {				if ((func_cur->busno == busno) && (func_cur->device == device) && (func_cur->function == function))					return func_cur;				func_cur = func_cur->next;			}		}	}	return NULL;}/************************************************************* * This routine frees up memory used by struct slot, including * the pointers to pci_func, bus, hotplug_slot, controller, * and deregistering from the hotplug core *************************************************************/static void free_slots (void){	struct slot *slot_cur;	struct list_head * tmp;	struct list_head * next;	debug ("%s -- enter\n", __FUNCTION__);	list_for_each_safe (tmp, next, &ibmphp_slot_head) {		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);		pci_hp_deregister (slot_cur->hotplug_slot);	}	debug ("%s -- exit\n", __FUNCTION__);}static void ibm_unconfigure_device(struct pci_func *func){	struct pci_dev *temp;	u8 j;	debug("inside %s\n", __FUNCTION__);	debug("func->device = %x, func->function = %x\n", func->device, func->function);	debug("func->device << 3 | 0x0  = %x\n", func->device << 3 | 0x0);	for (j = 0; j < 0x08; j++) {		temp = pci_find_slot(func->busno, (func->device << 3) | j);		if (temp)			pci_remove_bus_device(temp);	}}/* * The following function is to fix kernel bug regarding  * getting bus entries, here we manually add those primary  * bus entries to kernel bus structure whenever apply */static u8 bus_structure_fixup (u8 busno){	struct pci_bus *bus;	struct pci_dev *dev;	u16 l;	if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num (busno)))		return 1;	bus = kmalloc (sizeof (*bus), GFP_KERNEL);	if (!bus) {		err ("%s - out of memory\n", __FUNCTION__);		return 1;	}	dev = kmalloc (sizeof (*dev), GFP_KERNEL);	if (!dev) {		kfree (bus);		err ("%s - out of memory\n", __FUNCTION__);		return 1;	}	bus->number = busno;	bus->ops = ibmphp_pci_bus->ops;	dev->bus = bus;	for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {		if (!pci_read_config_word (dev, PCI_VENDOR_ID, &l) &&  l != 0x0000 && l != 0xffff) {			debug ("%s - Inside bus_struture_fixup()\n", __FUNCTION__);			pci_scan_bus (busno, ibmphp_pci_bus->ops, NULL);			break;		}	}	kfree (dev);	kfree (bus);	return 0;}static int ibm_configure_device (struct pci_func *func){	unsigned char bus;	struct pci_bus *child;	int num;	int flag = 0;	/* this is to make sure we don't double scan the bus, for bridged devices primarily */	if (!(bus_structure_fixup (func->busno)))		flag = 1;	if (func->dev == NULL)		func->dev = pci_find_slot (func->busno, PCI_DEVFN(func->device, func->function));	if (func->dev == NULL) {		struct pci_bus *bus = pci_find_bus(0, func->busno);		if (!bus)			return 0;		num = pci_scan_slot(bus, PCI_DEVFN(func->device, func->function));		if (num)			pci_bus_add_devices(bus);		func->dev = pci_find_slot(func->busno, PCI_DEVFN(func->device, func->function));		if (func->dev == NULL) {			err ("ERROR... : pci_dev still NULL\n");			return 0;		}	}	if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {		pci_read_config_byte (func->dev, PCI_SECONDARY_BUS, &bus);		child = (struct pci_bus *) pci_add_new_bus (func->dev->bus, (func->dev), bus);		pci_do_scan_bus (child);	}	return 0;}/******************************************************* * Returns whether the bus is empty or not  *******************************************************/static int is_bus_empty (struct slot * slot_cur){	int rc;	struct slot * tmp_slot;	u8 i = slot_cur->bus_on->slot_min;	while (i <= slot_cur->bus_on->slot_max) {		if (i == slot_cur->number) {			i++;			continue;		}		tmp_slot = ibmphp_get_slot_from_physical_num (i);		if (!tmp_slot)			return 0;		rc = slot_update (&tmp_slot);		if (rc)			return 0;		if (SLOT_PRESENT (tmp_slot->status) && SLOT_PWRGD (tmp_slot->status))			return 0;		i++;	}	return 1;}/*********************************************************** * If the HPC permits and the bus currently empty, tries to set the  * bus speed and mode at the maximum card and bus capability * Parameters: slot * Returns: bus is set (0) or error code ***********************************************************/static int set_bus (struct slot * slot_cur){	int rc;	u8 speed;	u8 cmd = 0x0;	struct pci_dev *dev = NULL;	int retval;	debug ("%s - entry slot # %d\n", __FUNCTION__, slot_cur->number);	if (SET_BUS_STATUS (slot_cur->ctrl) && is_bus_empty (slot_cur)) {		rc = slot_update (&slot_cur);		if (rc)			return rc;		speed = SLOT_SPEED (slot_cur->ext_status);		debug ("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);		switch (speed) {		case HPC_SLOT_SPEED_33:			cmd = HPC_BUS_33CONVMODE;			break;		case HPC_SLOT_SPEED_66:			if (SLOT_PCIX (slot_cur->ext_status)) {				if ((slot_cur->supported_speed >= BUS_SPEED_66) && (slot_cur->supported_bus_mode == BUS_MODE_PCIX))					cmd = HPC_BUS_66PCIXMODE;				else if (!SLOT_BUS_MODE (slot_cur->ext_status))					/* if max slot/bus capability is 66 pci					and there's no bus mode mismatch, then					the adapter supports 66 pci */ 					cmd = HPC_BUS_66CONVMODE;				else					cmd = HPC_BUS_33CONVMODE;			} else {				if (slot_cur->supported_speed >= BUS_SPEED_66)					cmd = HPC_BUS_66CONVMODE;				else					cmd = HPC_BUS_33CONVMODE;			}			break;		case HPC_SLOT_SPEED_133:			switch (slot_cur->supported_speed) {			case BUS_SPEED_33:				cmd = HPC_BUS_33CONVMODE;				break;			case BUS_SPEED_66:				if (slot_cur->supported_bus_mode == BUS_MODE_PCIX)					cmd = HPC_BUS_66PCIXMODE;				else					cmd = HPC_BUS_66CONVMODE;				break;			case BUS_SPEED_100:				cmd = HPC_BUS_100PCIXMODE;				break;			case BUS_SPEED_133:				/* This is to take care of the bug in CIOBX chip */				while ((dev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS,							      0x0101, dev)) != NULL)					ibmphp_hpc_writeslot (slot_cur, HPC_BUS_100PCIXMODE);				cmd = HPC_BUS_133PCIXMODE;				break;			default:				err ("Wrong bus speed\n");				return -ENODEV;			}			break;		default:			err ("wrong slot speed\n");			return -ENODEV;		}

⌨️ 快捷键说明

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