static ssize_t tpm_read(struct file *file, char __user *buf, size_t size, loff_t *off) { struct file_priv *priv = file->private_data; ssize_t ret_size; int rc; del_singleshot_timer_sync(&priv->user_read_timer); flush_work(&priv->work); ret_size = atomic_read(&priv->data_pending); if (ret_size > 0) { /* relay data */ ssize_t orig_ret_size = ret_size; if (size < ret_size) ret_size = size; mutex_lock(&priv->buffer_mutex); rc = copy_to_user(buf, priv->data_buffer, ret_size); memset(priv->data_buffer, 0, orig_ret_size); if (rc) ret_size = -EFAULT; mutex_unlock(&priv->buffer_mutex); } atomic_set(&priv->data_pending, 0); return ret_size; }
/* * Called on file close */ void tpm_common_release(struct file *file, struct file_priv *priv) { flush_work(&priv->async_work); del_singleshot_timer_sync(&priv->user_read_timer); flush_work(&priv->timeout_work); file->private_data = NULL; priv->response_length = 0; }
/* * Called on file close */ static int tpm_release(struct inode *inode, struct file *file) { struct file_priv *priv = file->private_data; del_singleshot_timer_sync(&priv->user_read_timer); flush_work(&priv->work); file->private_data = NULL; atomic_set(&priv->data_pending, 0); clear_bit(0, &priv->chip->is_open); kfree(priv); return 0; }
/* * caller should make sure no race with other threads */ static void ctx_clear_timer_kr(struct ptlrpc_cli_ctx *ctx) { struct gss_cli_ctx_keyring *gctx_kr = ctx2gctx_keyring(ctx); struct timer_list *timer = gctx_kr->gck_timer; if (timer == NULL) return; CDEBUG(D_SEC, "ctx %p, key %p\n", ctx, gctx_kr->gck_key); gctx_kr->gck_timer = NULL; del_singleshot_timer_sync(timer); OBD_FREE_PTR(timer); }
/* * See if the other side has responded to a partition deactivate request * from us. Though we requested the remote partition to deactivate with regard * to us, we really only need to wait for the other side to disengage from us. */ int xpc_partition_disengaged(struct xpc_partition *part) { short partid = XPC_PARTID(part); int disengaged; disengaged = !xpc_partition_engaged(partid); if (part->disengage_timeout) { if (!disengaged) { if (time_is_after_jiffies(part->disengage_timeout)) { /* timelimit hasn't been reached yet */ return 0; } /* * Other side hasn't responded to our deactivate * request in a timely fashion, so assume it's dead. */ dev_info(xpc_part, "deactivate request to remote " "partition %d timed out\n", partid); xpc_disengage_timedout = 1; xpc_assume_partition_disengaged(partid); disengaged = 1; } part->disengage_timeout = 0; /* cancel the timer function, provided it's not us */ if (!in_interrupt()) del_singleshot_timer_sync(&part->disengage_timer); DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING && part->act_state != XPC_P_AS_INACTIVE); if (part->act_state != XPC_P_AS_INACTIVE) xpc_wakeup_channel_mgr(part); xpc_cancel_partition_deactivation_request(part); } return disengaged; }
ssize_t tpm_common_read(struct file *file, char __user *buf, size_t size, loff_t *off) { struct file_priv *priv = file->private_data; ssize_t ret_size = 0; int rc; mutex_lock(&priv->buffer_mutex); if (priv->response_length) { priv->response_read = true; ret_size = min_t(ssize_t, size, priv->response_length); if (!ret_size) { priv->response_length = 0; goto out; } rc = copy_to_user(buf, priv->data_buffer + *off, ret_size); if (rc) { memset(priv->data_buffer, 0, TPM_BUFSIZE); priv->response_length = 0; ret_size = -EFAULT; } else { memset(priv->data_buffer + *off, 0, ret_size); priv->response_length -= ret_size; *off += ret_size; } } out: if (!priv->response_length) { *off = 0; del_singleshot_timer_sync(&priv->user_read_timer); flush_work(&priv->timeout_work); } mutex_unlock(&priv->buffer_mutex); return ret_size; }
static void prism2sta_disconnect_usb(struct usb_interface *interface) { wlandevice_t *wlandev; wlandev = (wlandevice_t *)usb_get_intfdata(interface); if (wlandev != NULL) { LIST_HEAD(cleanlist); hfa384x_usbctlx_t *ctlx, *temp; unsigned long flags; hfa384x_t *hw = wlandev->priv; if (!hw) goto exit; spin_lock_irqsave(&hw->ctlxq.lock, flags); p80211netdev_hwremoved(wlandev); list_splice_init(&hw->ctlxq.reapable, &cleanlist); list_splice_init(&hw->ctlxq.completing, &cleanlist); list_splice_init(&hw->ctlxq.pending, &cleanlist); list_splice_init(&hw->ctlxq.active, &cleanlist); spin_unlock_irqrestore(&hw->ctlxq.lock, flags); /* There's no hardware to shutdown, but the driver * might have some tasks or tasklets that must be * stopped before we can tear everything down. */ prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable); del_singleshot_timer_sync(&hw->throttle); del_singleshot_timer_sync(&hw->reqtimer); del_singleshot_timer_sync(&hw->resptimer); /* Unlink all the URBs. This "removes the wheels" * from the entire CTLX handling mechanism. */ usb_kill_urb(&hw->rx_urb); usb_kill_urb(&hw->tx_urb); usb_kill_urb(&hw->ctlx_urb); tasklet_kill(&hw->completion_bh); tasklet_kill(&hw->reaper_bh); cancel_work_sync(&hw->link_bh); cancel_work_sync(&hw->commsqual_bh); /* Now we complete any outstanding commands * and tell everyone who is waiting for their * responses that we have shut down. */ list_for_each_entry(ctlx, &cleanlist, list) complete(&ctlx->done); /* Give any outstanding synchronous commands * a chance to complete. All they need to do * is "wake up", so that's easy. * (I'd like a better way to do this, really.) */ msleep(100); /* Now delete the CTLXs, because no-one else can now. */ list_for_each_entry_safe(ctlx, temp, &cleanlist, list) kfree(ctlx); /* Unhook the wlandev */ unregister_wlandev(wlandev); wlan_unsetup(wlandev); usb_put_dev(hw->usb); hfa384x_destroy(hw); kfree(hw); kfree(wlandev); } exit: usb_set_intfdata(interface, NULL); }