Loading drivers/scsi/ufs/ufs-qcom-ice.c +71 −9 Original line number Diff line number Diff line /* * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -14,6 +14,7 @@ #include <linux/io.h> #include <linux/of.h> #include <linux/blkdev.h> #include <linux/spinlock.h> #include <crypto/ice.h> #include "ufs-qcom-ice.h" Loading Loading @@ -168,6 +169,7 @@ out: static void ufs_qcom_ice_cfg_work(struct work_struct *work) { unsigned long flags; struct ice_data_setting ice_set; struct ufs_qcom_host *qcom_host = container_of(work, struct ufs_qcom_host, ice_cfg_work); Loading @@ -185,12 +187,17 @@ static void ufs_qcom_ice_cfg_work(struct work_struct *work) qcom_host->ice.vops->config_start(qcom_host->ice.pdev, qcom_host->req_pending, &ice_set, false); spin_lock_irqsave(&qcom_host->ice_work_lock, flags); qcom_host->req_pending = NULL; spin_unlock_irqrestore(&qcom_host->ice_work_lock, flags); /* * Resume with requests processing. We assume config_start has been * successful, but even if it wasn't we still must resume in order to * allow for the request to be retried. */ ufshcd_scsi_unblock_requests(qcom_host->hba); } /** Loading Loading @@ -246,6 +253,7 @@ int ufs_qcom_ice_req_setup(struct ufs_qcom_host *qcom_host, struct ice_data_setting ice_set; char cmd_op = cmd->cmnd[0]; int err; unsigned long flags; if (!qcom_host->ice.pdev || !qcom_host->ice.vops) { dev_dbg(qcom_host->hba->dev, "%s: ice device is not enabled\n", Loading @@ -272,11 +280,33 @@ int ufs_qcom_ice_req_setup(struct ufs_qcom_host *qcom_host, dev_dbg(qcom_host->hba->dev, "%s: scheduling task for ice setup\n", __func__); qcom_host->req_pending = cmd->request; if (schedule_work(&qcom_host->ice_cfg_work)) spin_lock_irqsave( &qcom_host->ice_work_lock, flags); if (!qcom_host->req_pending) { ufshcd_scsi_block_requests( qcom_host->hba); qcom_host->req_pending = cmd->request; if (!schedule_work( &qcom_host->ice_cfg_work)) { qcom_host->req_pending = NULL; spin_unlock_irqrestore( &qcom_host->ice_work_lock, flags); ufshcd_scsi_unblock_requests( qcom_host->hba); return err; } } spin_unlock_irqrestore( &qcom_host->ice_work_lock, flags); } else { if (err != -EBUSY) dev_err(qcom_host->hba->dev, "%s: error in ice_vops->config %d\n", __func__, err); Loading Loading @@ -320,6 +350,7 @@ int ufs_qcom_ice_cfg_start(struct ufs_qcom_host *qcom_host, unsigned int bypass = 0; struct request *req; char cmd_op; unsigned long flags; if (!qcom_host->ice.pdev || !qcom_host->ice.vops) { dev_dbg(dev, "%s: ice device is not enabled\n", __func__); Loading Loading @@ -365,12 +396,43 @@ int ufs_qcom_ice_cfg_start(struct ufs_qcom_host *qcom_host, * request processing. */ if (err == -EAGAIN) { qcom_host->req_pending = req; if (schedule_work(&qcom_host->ice_cfg_work)) dev_dbg(qcom_host->hba->dev, "%s: scheduling task for ice setup\n", __func__); spin_lock_irqsave( &qcom_host->ice_work_lock, flags); if (!qcom_host->req_pending) { ufshcd_scsi_block_requests( qcom_host->hba); qcom_host->req_pending = cmd->request; if (!schedule_work( &qcom_host->ice_cfg_work)) { qcom_host->req_pending = NULL; spin_unlock_irqrestore( &qcom_host->ice_work_lock, flags); ufshcd_scsi_unblock_requests( qcom_host->hba); return err; } goto out; } spin_unlock_irqrestore( &qcom_host->ice_work_lock, flags); } else { if (err != -EBUSY) dev_err(qcom_host->hba->dev, "%s: error in ice_vops->config %d\n", __func__, err); } return err; } } Loading drivers/scsi/ufs/ufs-qcom.c +3 −1 Original line number Diff line number Diff line /* * Copyright (c) 2013-2016, Linux Foundation. All rights reserved. * Copyright (c) 2013-2017, Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -1981,6 +1981,8 @@ static int ufs_qcom_init(struct ufs_hba *hba) /* Make a two way bind between the qcom host and the hba */ host->hba = hba; spin_lock_init(&host->ice_work_lock); ufshcd_set_variant(hba, host); err = ufs_qcom_ice_get_dev(host); Loading drivers/scsi/ufs/ufs-qcom.h +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -370,6 +370,7 @@ struct ufs_qcom_host { u32 dbg_print_en; struct ufs_qcom_testbus testbus; spinlock_t ice_work_lock; struct work_struct ice_cfg_work; struct request *req_pending; }; Loading drivers/scsi/ufs/ufshcd.c +6 −5 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ #include "ufshci.h" #include "ufs_quirks.h" #include "ufs-debugfs.h" #include "ufs-qcom.h" #define CREATE_TRACE_POINTS #include <trace/events/ufs.h> Loading security/pfe/pfk_kc.c +43 −7 Original line number Diff line number Diff line /* * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -100,6 +100,9 @@ struct kc_entry { struct task_struct *thread_pending; enum pfk_kc_entry_state state; /* ref count for the number of requests in the HW queue for this key */ int loaded_ref_cnt; int scm_error; }; Loading Loading @@ -520,6 +523,10 @@ int pfk_kc_load_key_start(const unsigned char *key, size_t key_size, if (entry_exists) { kc_update_timestamp(entry); entry->state = ACTIVE_ICE_LOADED; if (async) entry->loaded_ref_cnt++; break; } case (FREE): Loading @@ -529,8 +536,17 @@ int pfk_kc_load_key_start(const unsigned char *key, size_t key_size, entry->scm_error = ret; pr_err("%s: key load error (%d)\n", __func__, ret); } else { entry->state = ACTIVE_ICE_LOADED; kc_update_timestamp(entry); entry->state = ACTIVE_ICE_LOADED; /* * only increase ref cnt for async calls, * sync calls from within work thread do not pass * requests further to HW */ if (async) entry->loaded_ref_cnt++; } break; case (ACTIVE_ICE_PRELOAD): Loading @@ -539,6 +555,10 @@ int pfk_kc_load_key_start(const unsigned char *key, size_t key_size, break; case (ACTIVE_ICE_LOADED): kc_update_timestamp(entry); if (async) entry->loaded_ref_cnt++; break; case(SCM_ERROR): ret = entry->scm_error; Loading Loading @@ -572,6 +592,8 @@ void pfk_kc_load_key_end(const unsigned char *key, size_t key_size, const unsigned char *salt, size_t salt_size) { struct kc_entry *entry = NULL; struct task_struct *tmp_pending = NULL; int ref_cnt = 0; if (!kc_is_ready()) return; Loading @@ -591,14 +613,28 @@ void pfk_kc_load_key_end(const unsigned char *key, size_t key_size, if (!entry) { kc_spin_unlock(); pr_err("internal error, there should an entry to unlock\n"); return; } entry->state = INACTIVE; ref_cnt = --entry->loaded_ref_cnt; if (ref_cnt < 0) pr_err("internal error, ref count should never be negative\n"); /* wake-up invalidation if it's waiting for the entry to be released */ if (!ref_cnt) { entry->state = INACTIVE; /* * wake-up invalidation if it's waiting * for the entry to be released */ if (entry->thread_pending) { wake_up_process(entry->thread_pending); tmp_pending = entry->thread_pending; entry->thread_pending = NULL; kc_spin_unlock(); wake_up_process(tmp_pending); return; } } kc_spin_unlock(); Loading Loading
drivers/scsi/ufs/ufs-qcom-ice.c +71 −9 Original line number Diff line number Diff line /* * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -14,6 +14,7 @@ #include <linux/io.h> #include <linux/of.h> #include <linux/blkdev.h> #include <linux/spinlock.h> #include <crypto/ice.h> #include "ufs-qcom-ice.h" Loading Loading @@ -168,6 +169,7 @@ out: static void ufs_qcom_ice_cfg_work(struct work_struct *work) { unsigned long flags; struct ice_data_setting ice_set; struct ufs_qcom_host *qcom_host = container_of(work, struct ufs_qcom_host, ice_cfg_work); Loading @@ -185,12 +187,17 @@ static void ufs_qcom_ice_cfg_work(struct work_struct *work) qcom_host->ice.vops->config_start(qcom_host->ice.pdev, qcom_host->req_pending, &ice_set, false); spin_lock_irqsave(&qcom_host->ice_work_lock, flags); qcom_host->req_pending = NULL; spin_unlock_irqrestore(&qcom_host->ice_work_lock, flags); /* * Resume with requests processing. We assume config_start has been * successful, but even if it wasn't we still must resume in order to * allow for the request to be retried. */ ufshcd_scsi_unblock_requests(qcom_host->hba); } /** Loading Loading @@ -246,6 +253,7 @@ int ufs_qcom_ice_req_setup(struct ufs_qcom_host *qcom_host, struct ice_data_setting ice_set; char cmd_op = cmd->cmnd[0]; int err; unsigned long flags; if (!qcom_host->ice.pdev || !qcom_host->ice.vops) { dev_dbg(qcom_host->hba->dev, "%s: ice device is not enabled\n", Loading @@ -272,11 +280,33 @@ int ufs_qcom_ice_req_setup(struct ufs_qcom_host *qcom_host, dev_dbg(qcom_host->hba->dev, "%s: scheduling task for ice setup\n", __func__); qcom_host->req_pending = cmd->request; if (schedule_work(&qcom_host->ice_cfg_work)) spin_lock_irqsave( &qcom_host->ice_work_lock, flags); if (!qcom_host->req_pending) { ufshcd_scsi_block_requests( qcom_host->hba); qcom_host->req_pending = cmd->request; if (!schedule_work( &qcom_host->ice_cfg_work)) { qcom_host->req_pending = NULL; spin_unlock_irqrestore( &qcom_host->ice_work_lock, flags); ufshcd_scsi_unblock_requests( qcom_host->hba); return err; } } spin_unlock_irqrestore( &qcom_host->ice_work_lock, flags); } else { if (err != -EBUSY) dev_err(qcom_host->hba->dev, "%s: error in ice_vops->config %d\n", __func__, err); Loading Loading @@ -320,6 +350,7 @@ int ufs_qcom_ice_cfg_start(struct ufs_qcom_host *qcom_host, unsigned int bypass = 0; struct request *req; char cmd_op; unsigned long flags; if (!qcom_host->ice.pdev || !qcom_host->ice.vops) { dev_dbg(dev, "%s: ice device is not enabled\n", __func__); Loading Loading @@ -365,12 +396,43 @@ int ufs_qcom_ice_cfg_start(struct ufs_qcom_host *qcom_host, * request processing. */ if (err == -EAGAIN) { qcom_host->req_pending = req; if (schedule_work(&qcom_host->ice_cfg_work)) dev_dbg(qcom_host->hba->dev, "%s: scheduling task for ice setup\n", __func__); spin_lock_irqsave( &qcom_host->ice_work_lock, flags); if (!qcom_host->req_pending) { ufshcd_scsi_block_requests( qcom_host->hba); qcom_host->req_pending = cmd->request; if (!schedule_work( &qcom_host->ice_cfg_work)) { qcom_host->req_pending = NULL; spin_unlock_irqrestore( &qcom_host->ice_work_lock, flags); ufshcd_scsi_unblock_requests( qcom_host->hba); return err; } goto out; } spin_unlock_irqrestore( &qcom_host->ice_work_lock, flags); } else { if (err != -EBUSY) dev_err(qcom_host->hba->dev, "%s: error in ice_vops->config %d\n", __func__, err); } return err; } } Loading
drivers/scsi/ufs/ufs-qcom.c +3 −1 Original line number Diff line number Diff line /* * Copyright (c) 2013-2016, Linux Foundation. All rights reserved. * Copyright (c) 2013-2017, Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -1981,6 +1981,8 @@ static int ufs_qcom_init(struct ufs_hba *hba) /* Make a two way bind between the qcom host and the hba */ host->hba = hba; spin_lock_init(&host->ice_work_lock); ufshcd_set_variant(hba, host); err = ufs_qcom_ice_get_dev(host); Loading
drivers/scsi/ufs/ufs-qcom.h +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -370,6 +370,7 @@ struct ufs_qcom_host { u32 dbg_print_en; struct ufs_qcom_testbus testbus; spinlock_t ice_work_lock; struct work_struct ice_cfg_work; struct request *req_pending; }; Loading
drivers/scsi/ufs/ufshcd.c +6 −5 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ #include "ufshci.h" #include "ufs_quirks.h" #include "ufs-debugfs.h" #include "ufs-qcom.h" #define CREATE_TRACE_POINTS #include <trace/events/ufs.h> Loading
security/pfe/pfk_kc.c +43 −7 Original line number Diff line number Diff line /* * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -100,6 +100,9 @@ struct kc_entry { struct task_struct *thread_pending; enum pfk_kc_entry_state state; /* ref count for the number of requests in the HW queue for this key */ int loaded_ref_cnt; int scm_error; }; Loading Loading @@ -520,6 +523,10 @@ int pfk_kc_load_key_start(const unsigned char *key, size_t key_size, if (entry_exists) { kc_update_timestamp(entry); entry->state = ACTIVE_ICE_LOADED; if (async) entry->loaded_ref_cnt++; break; } case (FREE): Loading @@ -529,8 +536,17 @@ int pfk_kc_load_key_start(const unsigned char *key, size_t key_size, entry->scm_error = ret; pr_err("%s: key load error (%d)\n", __func__, ret); } else { entry->state = ACTIVE_ICE_LOADED; kc_update_timestamp(entry); entry->state = ACTIVE_ICE_LOADED; /* * only increase ref cnt for async calls, * sync calls from within work thread do not pass * requests further to HW */ if (async) entry->loaded_ref_cnt++; } break; case (ACTIVE_ICE_PRELOAD): Loading @@ -539,6 +555,10 @@ int pfk_kc_load_key_start(const unsigned char *key, size_t key_size, break; case (ACTIVE_ICE_LOADED): kc_update_timestamp(entry); if (async) entry->loaded_ref_cnt++; break; case(SCM_ERROR): ret = entry->scm_error; Loading Loading @@ -572,6 +592,8 @@ void pfk_kc_load_key_end(const unsigned char *key, size_t key_size, const unsigned char *salt, size_t salt_size) { struct kc_entry *entry = NULL; struct task_struct *tmp_pending = NULL; int ref_cnt = 0; if (!kc_is_ready()) return; Loading @@ -591,14 +613,28 @@ void pfk_kc_load_key_end(const unsigned char *key, size_t key_size, if (!entry) { kc_spin_unlock(); pr_err("internal error, there should an entry to unlock\n"); return; } entry->state = INACTIVE; ref_cnt = --entry->loaded_ref_cnt; if (ref_cnt < 0) pr_err("internal error, ref count should never be negative\n"); /* wake-up invalidation if it's waiting for the entry to be released */ if (!ref_cnt) { entry->state = INACTIVE; /* * wake-up invalidation if it's waiting * for the entry to be released */ if (entry->thread_pending) { wake_up_process(entry->thread_pending); tmp_pending = entry->thread_pending; entry->thread_pending = NULL; kc_spin_unlock(); wake_up_process(tmp_pending); return; } } kc_spin_unlock(); Loading