2006-09-20 15:58:25 +02:00
/*
2012-08-28 16:41:50 +02:00
* Copyright IBM Corp . 2006 , 2012
2006-09-20 15:58:25 +02:00
* Author ( s ) : Cornelia Huck < cornelia . huck @ de . ibm . com >
* Martin Schwidefsky < schwidefsky @ de . ibm . com >
* Ralph Wuerthner < rwuerthn @ de . ibm . com >
2008-12-25 13:38:41 +01:00
* Felix Beck < felix . beck @ de . ibm . com >
2011-07-24 10:48:25 +02:00
* Holger Dengler < hd @ linux . vnet . ibm . com >
2006-09-20 15:58:25 +02:00
*
* Adjunct processor bus header file .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 , or ( at your option )
* any later version .
*
* 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 .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# ifndef _AP_BUS_H_
# define _AP_BUS_H_
# include <linux/device.h>
# include <linux/types.h>
2016-11-08 07:09:13 +01:00
# include <asm/ap.h>
2006-09-20 15:58:25 +02:00
# define AP_DEVICES 64 /* Number of AP devices. */
2014-09-08 13:24:13 +02:00
# define AP_DOMAINS 256 /* Number of AP domains. */
2013-11-20 10:47:13 +01:00
# define AP_RESET_TIMEOUT (HZ*0.7) /* Time in ticks for reset timeouts. */
2006-09-20 15:58:25 +02:00
# define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */
# define AP_POLL_TIME 1 /* Time in ticks between receive polls. */
extern int ap_domain_index ;
2016-08-25 11:16:03 +02:00
extern spinlock_t ap_list_lock ;
extern struct list_head ap_card_list ;
2012-08-28 16:41:50 +02:00
static inline int ap_test_bit ( unsigned int * ptr , unsigned int nr )
2011-07-24 10:48:25 +02:00
{
2012-08-28 16:41:50 +02:00
return ( * ptr & ( 0x80000000u > > nr ) ) ! = 0 ;
2011-07-24 10:48:25 +02:00
}
2006-09-20 15:58:25 +02:00
# define AP_RESPONSE_NORMAL 0x00
# define AP_RESPONSE_Q_NOT_AVAIL 0x01
# define AP_RESPONSE_RESET_IN_PROGRESS 0x02
# define AP_RESPONSE_DECONFIGURED 0x03
# define AP_RESPONSE_CHECKSTOPPED 0x04
# define AP_RESPONSE_BUSY 0x05
2008-12-25 13:38:41 +01:00
# define AP_RESPONSE_INVALID_ADDRESS 0x06
# define AP_RESPONSE_OTHERWISE_CHANGED 0x07
2006-09-20 15:58:25 +02:00
# define AP_RESPONSE_Q_FULL 0x10
# define AP_RESPONSE_NO_PENDING_REPLY 0x10
# define AP_RESPONSE_INDEX_TOO_BIG 0x11
# define AP_RESPONSE_NO_FIRST_PART 0x13
# define AP_RESPONSE_MESSAGE_TOO_BIG 0x15
2009-12-07 12:51:55 +01:00
# define AP_RESPONSE_REQ_FAC_NOT_INST 0x16
2006-09-20 15:58:25 +02:00
2008-04-17 07:46:28 +02:00
/*
2006-09-20 15:58:25 +02:00
* Known device types
*/
# define AP_DEVICE_TYPE_PCICC 3
# define AP_DEVICE_TYPE_PCICA 4
# define AP_DEVICE_TYPE_PCIXCC 5
# define AP_DEVICE_TYPE_CEX2A 6
# define AP_DEVICE_TYPE_CEX2C 7
2009-12-07 12:51:56 +01:00
# define AP_DEVICE_TYPE_CEX3A 8
# define AP_DEVICE_TYPE_CEX3C 9
2012-08-28 16:48:29 +02:00
# define AP_DEVICE_TYPE_CEX4 10
2015-01-23 14:56:25 +01:00
# define AP_DEVICE_TYPE_CEX5 11
2016-10-12 15:58:14 +02:00
# define AP_DEVICE_TYPE_CEX6 12
2006-09-20 15:58:25 +02:00
2012-08-28 16:43:48 +02:00
/*
* Known function facilities
*/
# define AP_FUNC_MEX4K 1
# define AP_FUNC_CRT4K 2
# define AP_FUNC_COPRO 3
# define AP_FUNC_ACCEL 4
2013-11-20 10:47:13 +01:00
# define AP_FUNC_EP11 5
# define AP_FUNC_APXA 6
2012-08-28 16:43:48 +02:00
2015-06-17 16:19:15 +02:00
/*
* AP interrupt states
*/
# define AP_INTR_DISABLED 0 /* AP interrupt disabled */
# define AP_INTR_ENABLED 1 /* AP interrupt enabled */
2015-09-14 17:01:23 +02:00
/*
* AP device states
*/
enum ap_state {
AP_STATE_RESET_START ,
AP_STATE_RESET_WAIT ,
AP_STATE_SETIRQ_WAIT ,
AP_STATE_IDLE ,
AP_STATE_WORKING ,
AP_STATE_QUEUE_FULL ,
AP_STATE_SUSPEND_WAIT ,
AP_STATE_BORKED ,
NR_AP_STATES
} ;
/*
* AP device events
*/
enum ap_event {
AP_EVENT_POLL ,
AP_EVENT_TIMEOUT ,
NR_AP_EVENTS
} ;
/*
* AP wait behaviour
*/
enum ap_wait {
AP_WAIT_AGAIN , /* retry immediately */
AP_WAIT_TIMEOUT , /* wait for timeout */
AP_WAIT_INTERRUPT , /* wait for thin interrupt (if available) */
AP_WAIT_NONE , /* no wait */
NR_AP_WAIT
} ;
2007-07-10 11:24:19 +02:00
2006-09-20 15:58:25 +02:00
struct ap_device ;
struct ap_message ;
struct ap_driver {
struct device_driver driver ;
struct ap_device_id * ids ;
int ( * probe ) ( struct ap_device * ) ;
void ( * remove ) ( struct ap_device * ) ;
2016-08-25 11:16:03 +02:00
void ( * suspend ) ( struct ap_device * ) ;
void ( * resume ) ( struct ap_device * ) ;
2006-09-20 15:58:25 +02:00
} ;
# define to_ap_drv(x) container_of((x), struct ap_driver, driver)
int ap_driver_register ( struct ap_driver * , struct module * , char * ) ;
void ap_driver_unregister ( struct ap_driver * ) ;
struct ap_device {
struct device device ;
struct ap_driver * drv ; /* Pointer to AP device driver. */
2016-08-25 11:16:03 +02:00
int device_type ; /* AP device type. */
} ;
2006-09-20 15:58:25 +02:00
2016-08-25 11:16:03 +02:00
# define to_ap_dev(x) container_of((x), struct ap_device, device)
2015-09-14 17:01:23 +02:00
2016-08-25 11:16:03 +02:00
struct ap_card {
struct ap_device ap_dev ;
struct list_head list ; /* Private list of AP cards. */
struct list_head queues ; /* List of assoc. AP queues */
void * private ; /* ap driver private pointer. */
2014-10-02 14:48:46 +02:00
int raw_hwtype ; /* AP raw hardware type. */
2012-08-28 16:43:48 +02:00
unsigned int functions ; /* AP device function bitfield. */
2016-08-25 11:16:03 +02:00
int queue_depth ; /* AP queue depth.*/
int id ; /* AP card number. */
2016-10-14 14:34:51 +02:00
atomic_t total_request_count ; /* # requests ever for this AP device.*/
2016-08-25 11:16:03 +02:00
} ;
# define to_ap_card(x) container_of((x), struct ap_card, ap_dev.device)
2006-09-20 15:58:25 +02:00
2016-08-25 11:16:03 +02:00
struct ap_queue {
struct ap_device ap_dev ;
struct list_head list ; /* Private list of AP queues. */
struct ap_card * card ; /* Ptr to assoc. AP card. */
spinlock_t lock ; /* Per device lock. */
void * private ; /* ap driver private pointer. */
ap_qid_t qid ; /* AP queue id. */
2015-06-17 16:19:15 +02:00
int interrupt ; /* indicate if interrupts are enabled */
2006-09-20 15:58:25 +02:00
int queue_count ; /* # messages currently on AP queue. */
2016-08-25 11:16:03 +02:00
enum ap_state state ; /* State of the AP device. */
2006-09-20 15:58:25 +02:00
int pendingq_count ; /* # requests on pendingq list. */
int requestq_count ; /* # requests on requestq list. */
2016-10-14 14:34:51 +02:00
int total_request_count ; /* # requests ever for this AP device.*/
2016-08-25 11:16:03 +02:00
int request_timeout ; /* Request timout in jiffies. */
struct timer_list timeout ; /* Timer for request timeouts. */
struct list_head pendingq ; /* List of message sent to AP queue. */
struct list_head requestq ; /* List of message yet to be sent. */
2006-09-20 15:58:25 +02:00
struct ap_message * reply ; /* Per device reply message. */
} ;
2016-08-25 11:16:03 +02:00
# define to_ap_queue(x) container_of((x), struct ap_queue, ap_dev.device)
typedef enum ap_wait ( ap_func_t ) ( struct ap_queue * queue ) ;
2006-09-20 15:58:25 +02:00
struct ap_message {
struct list_head list ; /* Request queueing. */
unsigned long long psmid ; /* Message id. */
void * message ; /* Pointer to message buffer. */
size_t length ; /* Message length. */
2015-09-14 16:59:27 +02:00
int rc ; /* Return code for this message */
2006-09-20 15:58:25 +02:00
void * private ; /* ap driver private pointer. */
2009-12-07 12:51:55 +01:00
unsigned int special : 1 ; /* Used for special commands. */
2012-05-16 14:08:22 +02:00
/* receive is called from tasklet context */
2016-08-25 11:16:03 +02:00
void ( * receive ) ( struct ap_queue * , struct ap_message * ,
2012-05-16 14:08:22 +02:00
struct ap_message * ) ;
2006-09-20 15:58:25 +02:00
} ;
2009-12-07 12:51:54 +01:00
/**
* ap_init_message ( ) - Initialize ap_message .
* Initialize a message before using . Otherwise this might result in
* unexpected behaviour .
*/
static inline void ap_init_message ( struct ap_message * ap_msg )
{
ap_msg - > psmid = 0 ;
ap_msg - > length = 0 ;
2015-09-14 16:59:27 +02:00
ap_msg - > rc = 0 ;
2009-12-07 12:51:55 +01:00
ap_msg - > special = 0 ;
2012-05-16 14:08:22 +02:00
ap_msg - > receive = NULL ;
2009-12-07 12:51:54 +01:00
}
2016-08-25 11:16:03 +02:00
# define for_each_ap_card(_ac) \
list_for_each_entry ( _ac , & ap_card_list , list )
# define for_each_ap_queue(_aq, _ac) \
list_for_each_entry ( _aq , & ( _ac ) - > queues , list )
2008-04-17 07:46:28 +02:00
/*
2006-09-20 15:58:25 +02:00
* Note : don ' t use ap_send / ap_recv after using ap_queue_message
* for the first time . Otherwise the ap message queue will get
* confused .
*/
int ap_send ( ap_qid_t , unsigned long long , void * , size_t ) ;
int ap_recv ( ap_qid_t , unsigned long long * , void * , size_t ) ;
2016-08-25 11:16:03 +02:00
enum ap_wait ap_sm_event ( struct ap_queue * aq , enum ap_event event ) ;
enum ap_wait ap_sm_event_loop ( struct ap_queue * aq , enum ap_event event ) ;
void ap_queue_message ( struct ap_queue * aq , struct ap_message * ap_msg ) ;
void ap_cancel_message ( struct ap_queue * aq , struct ap_message * ap_msg ) ;
void ap_flush_queue ( struct ap_queue * aq ) ;
void * ap_airq_ptr ( void ) ;
void ap_wait ( enum ap_wait wait ) ;
void ap_request_timeout ( unsigned long data ) ;
2012-09-10 21:34:26 +02:00
void ap_bus_force_rescan ( void ) ;
2016-08-25 11:16:03 +02:00
void ap_queue_init_reply ( struct ap_queue * aq , struct ap_message * ap_msg ) ;
struct ap_queue * ap_queue_create ( ap_qid_t qid , int device_type ) ;
void ap_queue_remove ( struct ap_queue * aq ) ;
void ap_queue_suspend ( struct ap_device * ap_dev ) ;
void ap_queue_resume ( struct ap_device * ap_dev ) ;
struct ap_card * ap_card_create ( int id , int queue_depth , int device_type ,
unsigned int device_functions ) ;
2006-09-20 15:58:25 +02:00
int ap_module_init ( void ) ;
void ap_module_exit ( void ) ;
# endif /* _AP_BUS_H_ */