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

📄 ibmphp_core.c

📁 audio driver for hotplug pci on linux 2.6.27
💻 C
📖 第 1 页 / 共 3 页
字号:
	ibmphp_unlock_operations();	debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value);	return rc;}/*static int get_max_adapter_speed_1(struct hotplug_slot *hotplug_slot, u8 * value, u8 flag){	int rc = -ENODEV;	struct slot *pslot;	struct slot myslot;	debug("get_max_adapter_speed_1 - Entry hotplug_slot[%lx] pvalue[%lx]\n",						(ulong)hotplug_slot, (ulong) value);	if (flag)		ibmphp_lock_operations();	if (hotplug_slot && value) {		pslot = hotplug_slot->private;		if (pslot) {			memcpy(&myslot, 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 = 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", __func__);	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", __func__);}static void ibm_unconfigure_device(struct pci_func *func){	struct pci_dev *temp;	u8 j;	debug("inside %s\n", __func__);	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_get_bus_and_slot(func->busno, (func->device << 3) | j);		if (temp) {			pci_remove_bus_device(temp);			pci_dev_put(temp);		}	}	pci_dev_put(func->dev);}/* * 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", __func__);		return 1;	}	dev = kmalloc(sizeof(*dev), GFP_KERNEL);	if (!dev) {		kfree(bus);		err("%s - out of memory\n", __func__);		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",							__func__);			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_get_bus_and_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_get_bus_and_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 = 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;	int retval;	static struct pci_device_id ciobx[] = {		{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },	        { },	};		debug("%s - entry slot # %d\n", __func__, 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 */

⌨️ 快捷键说明

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