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

📄 ibmphp_hpc.c

📁 audio driver for hotplug pci on linux 2.6.27
💻 C
📖 第 1 页 / 共 3 页
字号:
				} else					timeout--;			}		}		ctlr_ptr->status = status;	}	// cleanup	// remove physical to logical address mapping	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))		iounmap (wpg_bbar);	free_hpc_access ();	debug_polling ("%s - Exit rc[%d]\n", __func__, rc);	return rc;}/*----------------------------------------------------------------------* Name:    get_hpc_access()** Action: make sure only one process can access HPC at one time*---------------------------------------------------------------------*/static void get_hpc_access (void){	mutex_lock(&sem_hpcaccess);}/*----------------------------------------------------------------------* Name:    free_hpc_access()*---------------------------------------------------------------------*/void free_hpc_access (void){	mutex_unlock(&sem_hpcaccess);}/*----------------------------------------------------------------------* Name:    ibmphp_lock_operations()** Action: make sure only one process can change the data structure*---------------------------------------------------------------------*/void ibmphp_lock_operations (void){	down (&semOperations);	to_debug = 1;}/*----------------------------------------------------------------------* Name:    ibmphp_unlock_operations()*---------------------------------------------------------------------*/void ibmphp_unlock_operations (void){	debug ("%s - Entry\n", __func__);	up (&semOperations);	to_debug = 0;	debug ("%s - Exit\n", __func__);}/*----------------------------------------------------------------------* Name:    poll_hpc()*---------------------------------------------------------------------*/#define POLL_LATCH_REGISTER	0#define POLL_SLOTS		1#define POLL_SLEEP		2static int poll_hpc(void *data){	struct slot myslot;	struct slot *pslot = NULL;	struct list_head *pslotlist;	int rc;	int poll_state = POLL_LATCH_REGISTER;	u8 oldlatchlow = 0x00;	u8 curlatchlow = 0x00;	int poll_count = 0;	u8 ctrl_count = 0x00;	debug ("%s - Entry\n", __func__);	while (!kthread_should_stop()) {		/* try to get the lock to do some kind of hardware access */		down (&semOperations);		switch (poll_state) {		case POLL_LATCH_REGISTER: 			oldlatchlow = curlatchlow;			ctrl_count = 0x00;			list_for_each (pslotlist, &ibmphp_slot_head) {				if (ctrl_count >= ibmphp_get_total_controllers())					break;				pslot = list_entry (pslotlist, struct slot, ibm_slot_list);				if (pslot->ctrl->ctlr_relative_id == ctrl_count) {					ctrl_count++;					if (READ_SLOT_LATCH (pslot->ctrl)) {						rc = ibmphp_hpc_readslot (pslot,									  READ_SLOTLATCHLOWREG,									  &curlatchlow);						if (oldlatchlow != curlatchlow)							process_changeinlatch (oldlatchlow,									       curlatchlow,									       pslot->ctrl);					}				}			}			++poll_count;			poll_state = POLL_SLEEP;			break;		case POLL_SLOTS:			list_for_each (pslotlist, &ibmphp_slot_head) {				pslot = list_entry (pslotlist, struct slot, ibm_slot_list);				// make a copy of the old status				memcpy ((void *) &myslot, (void *) pslot,					sizeof (struct slot));				rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);				if ((myslot.status != pslot->status)				    || (myslot.ext_status != pslot->ext_status))					process_changeinstatus (pslot, &myslot);			}			ctrl_count = 0x00;			list_for_each (pslotlist, &ibmphp_slot_head) {				if (ctrl_count >= ibmphp_get_total_controllers())					break;				pslot = list_entry (pslotlist, struct slot, ibm_slot_list);				if (pslot->ctrl->ctlr_relative_id == ctrl_count) {					ctrl_count++;					if (READ_SLOT_LATCH (pslot->ctrl))						rc = ibmphp_hpc_readslot (pslot,									  READ_SLOTLATCHLOWREG,									  &curlatchlow);				}			}			++poll_count;			poll_state = POLL_SLEEP;			break;		case POLL_SLEEP:			/* don't sleep with a lock on the hardware */			up (&semOperations);			msleep(POLL_INTERVAL_SEC * 1000);			if (kthread_should_stop())				break;						down (&semOperations);						if (poll_count >= POLL_LATCH_CNT) {				poll_count = 0;				poll_state = POLL_SLOTS;			} else				poll_state = POLL_LATCH_REGISTER;			break;		}			/* give up the hardware semaphore */		up (&semOperations);		/* sleep for a short time just for good measure */		msleep(100);	}	up (&sem_exit);	debug ("%s - Exit\n", __func__);	return 0;}/*----------------------------------------------------------------------* Name:    process_changeinstatus** Action:  compare old and new slot status, process the change in status** Input:   pointer to slot struct, old slot struct** Return   0 or error codes* Value:** Side* Effects: None.** Notes:*---------------------------------------------------------------------*/static int process_changeinstatus (struct slot *pslot, struct slot *poldslot){	u8 status;	int rc = 0;	u8 disable = 0;	u8 update = 0;	debug ("process_changeinstatus - Entry pslot[%p], poldslot[%p]\n", pslot, poldslot);	// bit 0 - HPC_SLOT_POWER	if ((pslot->status & 0x01) != (poldslot->status & 0x01))		update = 1;	// bit 1 - HPC_SLOT_CONNECT	// ignore	// bit 2 - HPC_SLOT_ATTN	if ((pslot->status & 0x04) != (poldslot->status & 0x04))		update = 1;	// bit 3 - HPC_SLOT_PRSNT2	// bit 4 - HPC_SLOT_PRSNT1	if (((pslot->status & 0x08) != (poldslot->status & 0x08))		|| ((pslot->status & 0x10) != (poldslot->status & 0x10)))		update = 1;	// bit 5 - HPC_SLOT_PWRGD	if ((pslot->status & 0x20) != (poldslot->status & 0x20))		// OFF -> ON: ignore, ON -> OFF: disable slot		if ((poldslot->status & 0x20) && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) 			disable = 1;	// bit 6 - HPC_SLOT_BUS_SPEED	// ignore	// bit 7 - HPC_SLOT_LATCH	if ((pslot->status & 0x80) != (poldslot->status & 0x80)) {		update = 1;		// OPEN -> CLOSE		if (pslot->status & 0x80) {			if (SLOT_PWRGD (pslot->status)) {				// power goes on and off after closing latch				// check again to make sure power is still ON				msleep(1000);				rc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &status);				if (SLOT_PWRGD (status))					update = 1;				else	// overwrite power in pslot to OFF					pslot->status &= ~HPC_SLOT_POWER;			}		}		// CLOSE -> OPEN 		else if ((SLOT_PWRGD (poldslot->status) == HPC_SLOT_PWRGD_GOOD)			&& (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) {			disable = 1;		}		// else - ignore	}	// bit 4 - HPC_SLOT_BLINK_ATTN	if ((pslot->ext_status & 0x08) != (poldslot->ext_status & 0x08))		update = 1;	if (disable) {		debug ("process_changeinstatus - disable slot\n");		pslot->flag = 0;		rc = ibmphp_do_disable_slot (pslot);	}	if (update || disable) {		ibmphp_update_slot_info (pslot);	}	debug ("%s - Exit rc[%d] disable[%x] update[%x]\n", __func__, rc, disable, update);	return rc;}/*----------------------------------------------------------------------* Name:    process_changeinlatch** Action:  compare old and new latch reg status, process the change** Input:   old and current latch register status** Return   0 or error codes* Value:*---------------------------------------------------------------------*/static int process_changeinlatch (u8 old, u8 new, struct controller *ctrl){	struct slot myslot, *pslot;	u8 i;	u8 mask;	int rc = 0;	debug ("%s - Entry old[%x], new[%x]\n", __func__, old, new);	// bit 0 reserved, 0 is LSB, check bit 1-6 for 6 slots	for (i = ctrl->starting_slot_num; i <= ctrl->ending_slot_num; i++) {		mask = 0x01 << i;		if ((mask & old) != (mask & new)) {			pslot = ibmphp_get_slot_from_physical_num (i);			if (pslot) {				memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));				rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);				debug ("%s - call process_changeinstatus for slot[%d]\n", __func__, i);				process_changeinstatus (pslot, &myslot);			} else {				rc = -EINVAL;				err ("%s - Error bad pointer for slot[%d]\n", __func__, i);			}		}	}	debug ("%s - Exit rc[%d]\n", __func__, rc);	return rc;}/*----------------------------------------------------------------------* Name:    ibmphp_hpc_start_poll_thread** Action:  start polling thread*---------------------------------------------------------------------*/int __init ibmphp_hpc_start_poll_thread (void){	debug ("%s - Entry\n", __func__);	ibmphp_poll_thread = kthread_run(poll_hpc, NULL, "hpc_poll");	if (IS_ERR(ibmphp_poll_thread)) {		err ("%s - Error, thread not started\n", __func__);		return PTR_ERR(ibmphp_poll_thread);	}	return 0;}/*----------------------------------------------------------------------* Name:    ibmphp_hpc_stop_poll_thread** Action:  stop polling thread and cleanup*---------------------------------------------------------------------*/void __exit ibmphp_hpc_stop_poll_thread (void){	debug ("%s - Entry\n", __func__);	kthread_stop(ibmphp_poll_thread);	debug ("before locking operations \n");	ibmphp_lock_operations ();	debug ("after locking operations \n");		// wait for poll thread to exit	debug ("before sem_exit down \n");	down (&sem_exit);	debug ("after sem_exit down \n");	// cleanup	debug ("before free_hpc_access \n");	free_hpc_access ();	debug ("after free_hpc_access \n");	ibmphp_unlock_operations ();	debug ("after unlock operations \n");	up (&sem_exit);	debug ("after sem exit up\n");	debug ("%s - Exit\n", __func__);}/*----------------------------------------------------------------------* Name:    hpc_wait_ctlr_notworking** Action:  wait until the controller is in a not working state** Return   0, HPC_ERROR* Value:*---------------------------------------------------------------------*/static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, void __iomem *wpg_bbar,				    u8 * pstatus){	int rc = 0;	u8 done = 0;	debug_polling ("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout);	while (!done) {		*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX);		if (*pstatus == HPC_ERROR) {			rc = HPC_ERROR;			done = 1;		}		if (CTLR_WORKING (*pstatus) == HPC_CTLR_WORKING_NO)			done = 1;		if (!done) {			msleep(1000);			if (timeout < 1) {				done = 1;				err ("HPCreadslot - Error ctlr timeout\n");				rc = HPC_ERROR;			} else				timeout--;		}	}	debug_polling ("hpc_wait_ctlr_notworking - Exit rc[%x] status[%x]\n", rc, *pstatus);	return rc;}

⌨️ 快捷键说明

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