2014-06-05 13:42:39 -07:00
/*
This file is provided under a dual BSD / GPLv2 license . When using or
redistributing this file , you may do so under either license .
GPL LICENSE SUMMARY
Copyright ( c ) 2014 Intel Corporation .
This program is free software ; you can redistribute it and / or modify
it under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation .
This program is distributed in the hope that it will be useful , but
WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
General Public License for more details .
Contact Information :
qat - linux @ intel . com
BSD LICENSE
Copyright ( c ) 2014 Intel Corporation .
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions
are met :
* Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
* Redistributions in binary form must reproduce the above copyright
notice , this list of conditions and the following disclaimer in
the documentation and / or other materials provided with the
distribution .
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
" AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
# include <linux/mutex.h>
# include <linux/list.h>
# include <linux/bitops.h>
# include <linux/delay.h>
# include "adf_accel_devices.h"
# include "adf_cfg.h"
# include "adf_common_drv.h"
static LIST_HEAD ( service_table ) ;
static DEFINE_MUTEX ( service_lock ) ;
static void adf_service_add ( struct service_hndl * service )
{
mutex_lock ( & service_lock ) ;
list_add ( & service - > list , & service_table ) ;
mutex_unlock ( & service_lock ) ;
}
int adf_service_register ( struct service_hndl * service )
{
2016-12-22 15:01:02 +00:00
memset ( service - > init_status , 0 , sizeof ( service - > init_status ) ) ;
memset ( service - > start_status , 0 , sizeof ( service - > start_status ) ) ;
2014-06-05 13:42:39 -07:00
adf_service_add ( service ) ;
return 0 ;
}
static void adf_service_remove ( struct service_hndl * service )
{
mutex_lock ( & service_lock ) ;
list_del ( & service - > list ) ;
mutex_unlock ( & service_lock ) ;
}
int adf_service_unregister ( struct service_hndl * service )
{
2016-12-22 15:01:02 +00:00
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 ;
}
2014-06-05 13:42:39 -07:00
}
adf_service_remove ( service ) ;
return 0 ;
}
/**
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
* adf_dev_init ( ) - Init data structures and services for the given accel device
* @ accel_dev : Pointer to acceleration device .
2014-06-05 13:42:39 -07:00
*
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
* Initialize the ring data structures and the admin comms and arbitration
* services .
2014-06-05 13:42:39 -07:00
*
2015-07-24 13:18:26 -07:00
* Return : 0 on success , error code otherwise .
2014-06-05 13:42:39 -07:00
*/
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
int adf_dev_init ( struct adf_accel_dev * accel_dev )
2014-06-05 13:42:39 -07:00
{
struct service_hndl * service ;
struct list_head * list_itr ;
struct adf_hw_device_data * hw_data = accel_dev - > hw_device ;
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
if ( ! hw_data ) {
dev_err ( & GET_DEV ( accel_dev ) ,
2015-03-19 16:03:44 -07:00
" Failed to init device - hw_data not set \n " ) ;
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
return - EFAULT ;
}
2014-06-05 13:42:39 -07:00
if ( ! test_bit ( ADF_STATUS_CONFIGURED , & accel_dev - > status ) ) {
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) , " Device not configured \n " ) ;
2014-06-05 13:42:39 -07:00
return - EFAULT ;
}
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
if ( adf_init_etr_data ( accel_dev ) ) {
dev_err ( & GET_DEV ( accel_dev ) , " Failed initialize etr \n " ) ;
return - EFAULT ;
}
if ( hw_data - > init_admin_comms & & hw_data - > init_admin_comms ( accel_dev ) ) {
dev_err ( & GET_DEV ( accel_dev ) , " Failed initialize admin comms \n " ) ;
return - EFAULT ;
}
if ( hw_data - > init_arb & & hw_data - > init_arb ( accel_dev ) ) {
dev_err ( & GET_DEV ( accel_dev ) , " Failed initialize hw arbiter \n " ) ;
return - EFAULT ;
}
hw_data - > enable_ints ( accel_dev ) ;
2014-06-05 13:42:39 -07:00
if ( adf_ae_init ( accel_dev ) ) {
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to initialise Acceleration Engine \n " ) ;
2014-06-05 13:42:39 -07:00
return - EFAULT ;
}
set_bit ( ADF_STATUS_AE_INITIALISED , & accel_dev - > status ) ;
if ( adf_ae_fw_load ( accel_dev ) ) {
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to load acceleration FW \n " ) ;
2014-06-05 13:42:39 -07:00
return - EFAULT ;
}
set_bit ( ADF_STATUS_AE_UCODE_LOADED , & accel_dev - > status ) ;
if ( hw_data - > alloc_irq ( accel_dev ) ) {
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) , " Failed to allocate interrupts \n " ) ;
2014-06-05 13:42:39 -07:00
return - EFAULT ;
}
set_bit ( ADF_STATUS_IRQ_ALLOCATED , & accel_dev - > status ) ;
/*
* 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 ( list_itr , & service_table ) {
service = list_entry ( list_itr , struct service_hndl , list ) ;
if ( service - > event_hld ( accel_dev , ADF_EVENT_INIT ) ) {
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to initialise service %s \n " ,
service - > name ) ;
2014-06-05 13:42:39 -07:00
return - EFAULT ;
}
2016-12-22 15:01:02 +00:00
set_bit ( accel_dev - > accel_id , service - > init_status ) ;
2014-06-05 13:42:39 -07:00
}
hw_data - > enable_error_correction ( accel_dev ) ;
2015-08-07 11:34:25 -07:00
hw_data - > enable_vf2pf_comms ( accel_dev ) ;
2014-06-05 13:42:39 -07:00
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
return 0 ;
}
EXPORT_SYMBOL_GPL ( adf_dev_init ) ;
/**
* 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 .
*
2015-07-24 13:18:26 -07:00
* Return : 0 on success , error code otherwise .
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
*/
int adf_dev_start ( struct adf_accel_dev * accel_dev )
{
2015-08-07 11:34:20 -07:00
struct adf_hw_device_data * hw_data = accel_dev - > hw_device ;
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
struct service_hndl * service ;
struct list_head * list_itr ;
set_bit ( ADF_STATUS_STARTING , & accel_dev - > status ) ;
2014-06-05 13:42:39 -07:00
if ( adf_ae_start ( accel_dev ) ) {
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) , " AE Start Failed \n " ) ;
2014-06-05 13:42:39 -07:00
return - EFAULT ;
}
set_bit ( ADF_STATUS_AE_STARTED , & accel_dev - > status ) ;
2015-08-07 11:34:20 -07:00
if ( hw_data - > send_admin_init ( accel_dev ) ) {
dev_err ( & GET_DEV ( accel_dev ) , " Failed to send init message \n " ) ;
return - EFAULT ;
2014-06-05 13:42:39 -07:00
}
2015-08-07 11:34:20 -07:00
2014-06-05 13:42:39 -07:00
list_for_each ( list_itr , & service_table ) {
service = list_entry ( list_itr , struct service_hndl , list ) ;
if ( service - > event_hld ( accel_dev , ADF_EVENT_START ) ) {
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to start service %s \n " ,
service - > name ) ;
2014-06-05 13:42:39 -07:00
return - EFAULT ;
}
2016-12-22 15:01:02 +00:00
set_bit ( accel_dev - > accel_id , service - > start_status ) ;
2014-06-05 13:42:39 -07:00
}
clear_bit ( ADF_STATUS_STARTING , & accel_dev - > status ) ;
set_bit ( ADF_STATUS_STARTED , & accel_dev - > status ) ;
2015-08-07 11:34:25 -07:00
if ( ! list_empty ( & accel_dev - > crypto_list ) & &
( qat_algs_register ( ) | | qat_asym_algs_register ( ) ) ) {
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to register crypto algs \n " ) ;
2014-06-05 13:42:39 -07:00
set_bit ( ADF_STATUS_STARTING , & accel_dev - > status ) ;
clear_bit ( ADF_STATUS_STARTED , & accel_dev - > status ) ;
return - EFAULT ;
}
return 0 ;
}
EXPORT_SYMBOL_GPL ( adf_dev_start ) ;
/**
* 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 .
*
2016-03-29 10:21:07 -07:00
* Return : void
2014-06-05 13:42:39 -07:00
*/
2016-03-29 10:21:07 -07:00
void adf_dev_stop ( struct adf_accel_dev * accel_dev )
2014-06-05 13:42:39 -07:00
{
struct service_hndl * service ;
struct list_head * list_itr ;
2015-01-09 11:55:04 -08:00
bool wait = false ;
int ret ;
2014-06-05 13:42:39 -07:00
if ( ! adf_dev_started ( accel_dev ) & &
2016-03-29 10:21:07 -07:00
! test_bit ( ADF_STATUS_STARTING , & accel_dev - > status ) )
return ;
2014-06-05 13:42:39 -07:00
clear_bit ( ADF_STATUS_STARTING , & accel_dev - > status ) ;
clear_bit ( ADF_STATUS_STARTED , & accel_dev - > status ) ;
2015-09-22 11:57:47 -07:00
if ( ! list_empty ( & accel_dev - > crypto_list ) ) {
qat_algs_unregister ( ) ;
2015-08-07 11:34:25 -07:00
qat_asym_algs_unregister ( ) ;
2015-09-22 11:57:47 -07:00
}
2015-07-15 15:28:38 -07:00
2014-06-05 13:42:39 -07:00
list_for_each ( list_itr , & service_table ) {
service = list_entry ( list_itr , struct service_hndl , list ) ;
2016-12-22 15:01:02 +00:00
if ( ! test_bit ( accel_dev - > accel_id , service - > start_status ) )
2014-06-05 13:42:39 -07:00
continue ;
ret = service - > event_hld ( accel_dev , ADF_EVENT_STOP ) ;
if ( ! ret ) {
2016-12-22 15:01:02 +00:00
clear_bit ( accel_dev - > accel_id , service - > start_status ) ;
2014-06-05 13:42:39 -07:00
} else if ( ret = = - EAGAIN ) {
2015-01-09 11:55:04 -08:00
wait = true ;
2016-12-22 15:01:02 +00:00
clear_bit ( accel_dev - > accel_id , service - > start_status ) ;
2014-06-05 13:42:39 -07:00
}
}
if ( wait )
msleep ( 100 ) ;
2015-01-09 11:55:09 -08:00
if ( test_bit ( ADF_STATUS_AE_STARTED , & accel_dev - > status ) ) {
2014-06-05 13:42:39 -07:00
if ( adf_ae_stop ( accel_dev ) )
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) , " failed to stop AE \n " ) ;
2014-06-05 13:42:39 -07:00
else
clear_bit ( ADF_STATUS_AE_STARTED , & accel_dev - > status ) ;
}
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
}
EXPORT_SYMBOL_GPL ( adf_dev_stop ) ;
/**
* 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 .
*/
void adf_dev_shutdown ( struct adf_accel_dev * accel_dev )
{
struct adf_hw_device_data * hw_data = accel_dev - > hw_device ;
struct service_hndl * service ;
struct list_head * list_itr ;
if ( ! hw_data ) {
dev_err ( & GET_DEV ( accel_dev ) ,
" QAT: Failed to shutdown device - hw_data not set \n " ) ;
return ;
}
2014-06-05 13:42:39 -07:00
if ( test_bit ( ADF_STATUS_AE_UCODE_LOADED , & accel_dev - > status ) ) {
2015-04-03 08:41:17 -07:00
adf_ae_fw_release ( accel_dev ) ;
clear_bit ( ADF_STATUS_AE_UCODE_LOADED , & accel_dev - > status ) ;
2014-06-05 13:42:39 -07:00
}
if ( test_bit ( ADF_STATUS_AE_INITIALISED , & accel_dev - > status ) ) {
if ( adf_ae_shutdown ( accel_dev ) )
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to shutdown Accel Engine \n " ) ;
2014-06-05 13:42:39 -07:00
else
clear_bit ( ADF_STATUS_AE_INITIALISED ,
& accel_dev - > status ) ;
}
list_for_each ( list_itr , & service_table ) {
service = list_entry ( list_itr , struct service_hndl , list ) ;
2016-12-22 15:01:02 +00:00
if ( ! test_bit ( accel_dev - > accel_id , service - > init_status ) )
2014-06-05 13:42:39 -07:00
continue ;
if ( service - > event_hld ( accel_dev , ADF_EVENT_SHUTDOWN ) )
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to shutdown service %s \n " ,
service - > name ) ;
2014-06-05 13:42:39 -07:00
else
2016-12-22 15:01:02 +00:00
clear_bit ( accel_dev - > accel_id , service - > init_status ) ;
2014-06-05 13:42:39 -07:00
}
2016-04-15 10:38:00 -07:00
hw_data - > disable_iov ( accel_dev ) ;
2014-06-05 13:42:39 -07:00
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 ) ;
}
/* Delete configuration only if not restarting */
if ( ! test_bit ( ADF_STATUS_RESTARTING , & accel_dev - > status ) )
adf_cfg_del_all ( accel_dev ) ;
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
if ( hw_data - > exit_arb )
hw_data - > exit_arb ( accel_dev ) ;
if ( hw_data - > exit_admin_comms )
hw_data - > exit_admin_comms ( accel_dev ) ;
adf_cleanup_etr_data ( accel_dev ) ;
2015-12-04 16:56:28 -08:00
adf_dev_restore ( accel_dev ) ;
2014-06-05 13:42:39 -07:00
}
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
EXPORT_SYMBOL_GPL ( adf_dev_shutdown ) ;
2014-06-05 13:42:39 -07:00
int adf_dev_restarting_notify ( struct adf_accel_dev * accel_dev )
{
struct service_hndl * service ;
struct list_head * list_itr ;
list_for_each ( list_itr , & service_table ) {
service = list_entry ( list_itr , struct service_hndl , list ) ;
if ( service - > event_hld ( accel_dev , ADF_EVENT_RESTARTING ) )
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to restart service %s. \n " ,
service - > name ) ;
2014-06-05 13:42:39 -07:00
}
return 0 ;
}
int adf_dev_restarted_notify ( struct adf_accel_dev * accel_dev )
{
struct service_hndl * service ;
struct list_head * list_itr ;
list_for_each ( list_itr , & service_table ) {
service = list_entry ( list_itr , struct service_hndl , list ) ;
if ( service - > event_hld ( accel_dev , ADF_EVENT_RESTARTED ) )
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to restart service %s. \n " ,
service - > name ) ;
2014-06-05 13:42:39 -07:00
}
return 0 ;
}