int adf_service_unregister(struct service_hndl *service)
{ int i;
for (i = 0; i < ARRAY_SIZE(service->init_status); i++) { if (service->init_status[i] || service->start_status[i]) {
pr_err("QAT: Could not remove active service\n"); return -EFAULT;
}
}
adf_service_remove(service); return 0;
}
/** * adf_dev_init() - Init data structures and services for the given accel device * @accel_dev: Pointer to acceleration device. * * Initialize the ring data structures and the admin comms and arbitration * services. * * Return: 0 on success, error code otherwise.
*/ staticint adf_dev_init(struct adf_accel_dev *accel_dev)
{ struct service_hndl *service; struct adf_hw_device_data *hw_data = accel_dev->hw_device; int ret;
if (!hw_data) {
dev_err(&GET_DEV(accel_dev), "Failed to init device - hw_data not set\n"); return -EFAULT;
}
if (!test_bit(ADF_STATUS_CONFIGURED, &accel_dev->status) &&
!accel_dev->is_vf) {
dev_err(&GET_DEV(accel_dev), "Device not configured\n"); return -EFAULT;
}
if (adf_init_etr_data(accel_dev)) {
dev_err(&GET_DEV(accel_dev), "Failed initialize etr\n"); return -EFAULT;
}
if (hw_data->init_device && hw_data->init_device(accel_dev)) {
dev_err(&GET_DEV(accel_dev), "Failed to initialize device\n"); return -EFAULT;
}
ret = hw_data->pfvf_ops.enable_comms(accel_dev); if (ret) return ret;
if (!test_bit(ADF_STATUS_CONFIGURED, &accel_dev->status) &&
accel_dev->is_vf) { if (qat_crypto_vf_dev_config(accel_dev)) return -EFAULT;
}
adf_heartbeat_init(accel_dev);
ret = adf_rl_init(accel_dev); if (ret && ret != -EOPNOTSUPP) return ret;
ret = adf_tl_init(accel_dev); if (ret && ret != -EOPNOTSUPP) return ret;
/* * Subservice initialisation is divided into two stages: init and start. * This is to facilitate any ordering dependencies between services * prior to starting any of the accelerators.
*/
list_for_each_entry(service, &service_table, list) { if (service->event_hld(accel_dev, ADF_EVENT_INIT)) {
dev_err(&GET_DEV(accel_dev), "Failed to initialise service %s\n",
service->name); return -EFAULT;
}
set_bit(accel_dev->accel_id, service->init_status);
}
return 0;
}
/** * adf_dev_start() - Start acceleration service for the given accel device * @accel_dev: Pointer to acceleration device. * * Function notifies all the registered services that the acceleration device * is ready to be used. * To be used by QAT device specific drivers. * * Return: 0 on success, error code otherwise.
*/ staticint adf_dev_start(struct adf_accel_dev *accel_dev)
{ struct adf_hw_device_data *hw_data = accel_dev->hw_device; struct service_hndl *service; int ret;
if (hw_data->send_admin_init(accel_dev)) {
dev_err(&GET_DEV(accel_dev), "Failed to send init message\n"); return -EFAULT;
}
if (hw_data->measure_clock) {
ret = hw_data->measure_clock(accel_dev); if (ret) {
dev_err(&GET_DEV(accel_dev), "Failed measure device clock\n"); return ret;
}
}
/* Set ssm watch dog timer */ if (hw_data->set_ssm_wdtimer)
hw_data->set_ssm_wdtimer(accel_dev);
/* Enable Power Management */ if (hw_data->enable_pm && hw_data->enable_pm(accel_dev)) {
dev_err(&GET_DEV(accel_dev), "Failed to configure Power Management\n"); return -EFAULT;
}
if (hw_data->start_timer) {
ret = hw_data->start_timer(accel_dev); if (ret) {
dev_err(&GET_DEV(accel_dev), "Failed to start internal sync timer\n"); return ret;
}
}
adf_heartbeat_start(accel_dev);
ret = adf_rl_start(accel_dev); if (ret && ret != -EOPNOTSUPP) return ret;
ret = adf_tl_start(accel_dev); if (ret && ret != -EOPNOTSUPP) return ret;
list_for_each_entry(service, &service_table, list) { if (service->event_hld(accel_dev, ADF_EVENT_START)) {
dev_err(&GET_DEV(accel_dev), "Failed to start service %s\n",
service->name); return -EFAULT;
}
set_bit(accel_dev->accel_id, service->start_status);
}
/** * adf_dev_stop() - Stop acceleration service for the given accel device * @accel_dev: Pointer to acceleration device. * * Function notifies all the registered services that the acceleration device * is shuting down. * To be used by QAT device specific drivers. * * Return: void
*/ staticvoid adf_dev_stop(struct adf_accel_dev *accel_dev)
{ struct adf_hw_device_data *hw_data = accel_dev->hw_device; struct service_hndl *service; bool wait = false; int ret;
if (!adf_dev_started(accel_dev) &&
!test_bit(ADF_STATUS_STARTING, &accel_dev->status)) return;
if (!list_empty(&accel_dev->compression_list) &&
test_bit(ADF_STATUS_COMP_ALGS_REGISTERED, &accel_dev->status))
qat_comp_algs_unregister();
clear_bit(ADF_STATUS_COMP_ALGS_REGISTERED, &accel_dev->status);
list_for_each_entry(service, &service_table, list) { if (!test_bit(accel_dev->accel_id, service->start_status)) continue;
ret = service->event_hld(accel_dev, ADF_EVENT_STOP); if (!ret) {
clear_bit(accel_dev->accel_id, service->start_status);
} elseif (ret == -EAGAIN) {
wait = true;
clear_bit(accel_dev->accel_id, service->start_status);
}
}
if (hw_data->stop_timer)
hw_data->stop_timer(accel_dev);
hw_data->disable_iov(accel_dev);
if (wait)
msleep(100);
if (test_bit(ADF_STATUS_AE_STARTED, &accel_dev->status)) { if (adf_ae_stop(accel_dev))
dev_err(&GET_DEV(accel_dev), "failed to stop AE\n"); else
clear_bit(ADF_STATUS_AE_STARTED, &accel_dev->status);
}
}
/** * adf_dev_shutdown() - shutdown acceleration services and data strucutures * @accel_dev: Pointer to acceleration device * * Cleanup the ring data structures and the admin comms and arbitration * services.
*/ staticvoid adf_dev_shutdown(struct adf_accel_dev *accel_dev)
{ struct adf_hw_device_data *hw_data = accel_dev->hw_device; struct service_hndl *service;
if (!hw_data) {
dev_err(&GET_DEV(accel_dev), "QAT: Failed to shutdown device - hw_data not set\n"); return;
}
if (test_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status)) {
adf_ae_fw_release(accel_dev);
clear_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status);
}
if (test_bit(ADF_STATUS_AE_INITIALISED, &accel_dev->status)) { if (adf_ae_shutdown(accel_dev))
dev_err(&GET_DEV(accel_dev), "Failed to shutdown Accel Engine\n"); else
clear_bit(ADF_STATUS_AE_INITIALISED,
&accel_dev->status);
}
list_for_each_entry(service, &service_table, list) { if (!test_bit(accel_dev->accel_id, service->init_status)) continue; if (service->event_hld(accel_dev, ADF_EVENT_SHUTDOWN))
dev_err(&GET_DEV(accel_dev), "Failed to shutdown service %s\n",
service->name); else
clear_bit(accel_dev->accel_id, service->init_status);
}
adf_rl_exit(accel_dev);
if (hw_data->ras_ops.disable_ras_errors)
hw_data->ras_ops.disable_ras_errors(accel_dev);
adf_heartbeat_shutdown(accel_dev);
adf_tl_shutdown(accel_dev);
if (test_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status)) {
hw_data->free_irq(accel_dev);
clear_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status);
}
/* If not restarting, delete all cfg sections except for GENERAL */ if (!test_bit(ADF_STATUS_RESTARTING, &accel_dev->status))
adf_cfg_del_all_except(accel_dev, ADF_GENERAL_SEC);
if (hw_data->exit_arb)
hw_data->exit_arb(accel_dev);
if (hw_data->exit_admin_comms)
hw_data->exit_admin_comms(accel_dev);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.