2019-05-29 07:18:06 -07:00
/* SPDX-License-Identifier: GPL-2.0-only */
2009-09-23 17:46:15 -07:00
/*
2015-11-26 03:54:45 -05:00
* Copyright ( c ) 2005 - 2014 Brocade Communications Systems , Inc .
* Copyright ( c ) 2014 - QLogic Corporation .
2009-09-23 17:46:15 -07:00
* All rights reserved
2015-11-26 03:54:45 -05:00
* www . qlogic . com
2009-09-23 17:46:15 -07:00
*
2015-11-26 03:54:46 -05:00
* Linux driver for QLogic BR - series Fibre Channel Host Bus Adapter .
2009-09-23 17:46:15 -07:00
*/
# ifndef __BFAD_IM_H__
# define __BFAD_IM_H__
2010-09-15 11:50:55 -07:00
# include "bfa_fcs.h"
2009-09-23 17:46:15 -07:00
# define FCPI_NAME " fcpim"
2010-09-15 11:50:55 -07:00
# ifndef KOBJ_NAME_LEN
# define KOBJ_NAME_LEN 20
# endif
2009-09-23 17:46:15 -07:00
bfa_status_t bfad_im_module_init ( void ) ;
void bfad_im_module_exit ( void ) ;
bfa_status_t bfad_im_probe ( struct bfad_s * bfad ) ;
void bfad_im_probe_undo ( struct bfad_s * bfad ) ;
bfa_status_t bfad_im_port_new ( struct bfad_s * bfad , struct bfad_port_s * port ) ;
void bfad_im_port_delete ( struct bfad_s * bfad , struct bfad_port_s * port ) ;
void bfad_im_port_clean ( struct bfad_im_port_s * im_port ) ;
int bfad_im_scsi_host_alloc ( struct bfad_s * bfad ,
2010-03-19 11:05:39 -07:00
struct bfad_im_port_s * im_port , struct device * dev ) ;
2009-09-23 17:46:15 -07:00
void bfad_im_scsi_host_free ( struct bfad_s * bfad ,
struct bfad_im_port_s * im_port ) ;
2012-05-11 17:49:59 -07:00
u32 bfad_im_supported_speeds ( struct bfa_s * bfa ) ;
2009-09-23 17:46:15 -07:00
# define MAX_FCP_TARGET 1024
# define MAX_FCP_LUN 16384
# define BFAD_TARGET_RESET_TMO 60
# define BFAD_LUN_RESET_TMO 60
# define BFA_QUEUE_FULL_RAMP_UP_TIME 120
/*
* itnim flags
*/
# define IO_DONE_BIT 0
struct bfad_itnim_data_s {
struct bfad_itnim_s * itnim ;
} ;
struct bfad_im_port_s {
struct bfad_s * bfad ;
struct bfad_port_s * port ;
struct work_struct port_delete_work ;
int idr_id ;
u16 cur_scsi_id ;
2010-09-15 11:50:55 -07:00
u16 flags ;
2009-09-23 17:46:15 -07:00
struct list_head binding_list ;
struct Scsi_Host * shost ;
struct list_head itnim_mapped_list ;
2010-03-19 11:05:39 -07:00
struct fc_vport * fc_vport ;
2009-09-23 17:46:15 -07:00
} ;
2017-12-06 15:14:18 +01:00
struct bfad_im_port_pointer {
struct bfad_im_port_s * p ;
} ;
static inline struct bfad_im_port_s * bfad_get_im_port ( struct Scsi_Host * host )
{
struct bfad_im_port_pointer * im_portp = shost_priv ( host ) ;
return im_portp - > p ;
}
2009-09-23 17:46:15 -07:00
enum bfad_itnim_state {
ITNIM_STATE_NONE ,
ITNIM_STATE_ONLINE ,
ITNIM_STATE_OFFLINE_PENDING ,
ITNIM_STATE_OFFLINE ,
ITNIM_STATE_TIMEOUT ,
ITNIM_STATE_FREE ,
} ;
/*
* Per itnim data structure
*/
struct bfad_itnim_s {
struct list_head list_entry ;
struct bfa_fcs_itnim_s fcs_itnim ;
struct work_struct itnim_work ;
u32 flags ;
enum bfad_itnim_state state ;
struct bfad_im_s * im ;
struct bfad_im_port_s * im_port ;
struct bfad_rport_s * drv_rport ;
struct fc_rport * fc_rport ;
struct bfa_itnim_s * bfa_itnim ;
u16 scsi_tgt_id ;
2011-12-20 18:58:32 -08:00
u16 channel ;
2009-09-23 17:46:15 -07:00
u16 queue_work ;
unsigned long last_ramp_up_time ;
unsigned long last_queue_full_time ;
} ;
enum bfad_binding_type {
FCP_PWWN_BINDING = 0x1 ,
FCP_NWWN_BINDING = 0x2 ,
FCP_FCID_BINDING = 0x3 ,
} ;
struct bfad_fcp_binding {
struct list_head list_entry ;
enum bfad_binding_type binding_type ;
u16 scsi_target_id ;
u32 fc_id ;
wwn_t nwwn ;
wwn_t pwwn ;
} ;
struct bfad_im_s {
struct bfad_s * bfad ;
struct workqueue_struct * drv_workq ;
2010-09-15 11:50:55 -07:00
char drv_workq_name [ KOBJ_NAME_LEN ] ;
2011-07-20 16:59:13 -07:00
struct work_struct aen_im_notify_work ;
2009-09-23 17:46:15 -07:00
} ;
2011-07-20 16:59:13 -07:00
# define bfad_get_aen_entry(_drv, _entry) do { \
unsigned long _flags ; \
spin_lock_irqsave ( & ( _drv ) - > bfad_aen_spinlock , _flags ) ; \
bfa_q_deq ( & ( _drv ) - > free_aen_q , & ( _entry ) ) ; \
if ( _entry ) \
list_add_tail ( & ( _entry ) - > qe , & ( _drv ) - > active_aen_q ) ; \
spin_unlock_irqrestore ( & ( _drv ) - > bfad_aen_spinlock , _flags ) ; \
} while ( 0 )
/* post fc_host vendor event */
2017-11-10 16:37:14 +01:00
static inline void bfad_im_post_vendor_event ( struct bfa_aen_entry_s * entry ,
struct bfad_s * drv , int cnt ,
enum bfa_aen_category cat ,
2018-09-27 16:56:52 -07:00
int evt )
2017-11-10 16:37:14 +01:00
{
struct timespec64 ts ;
ktime_get_real_ts64 ( & ts ) ;
/*
* ' unsigned long aen_tv_sec ' overflows in y2106 on 32 - bit
* architectures , or in 2038 if user space interprets it
* as ' signed ' .
*/
entry - > aen_tv_sec = ts . tv_sec ;
entry - > aen_tv_usec = ts . tv_nsec / NSEC_PER_USEC ;
entry - > bfad_num = drv - > inst_no ;
entry - > seq_num = cnt ;
entry - > aen_category = cat ;
entry - > aen_type = evt ;
if ( drv - > bfad_flags & BFAD_FC4_PROBE_DONE )
queue_work ( drv - > im - > drv_workq , & drv - > im - > aen_im_notify_work ) ;
}
2011-07-20 16:59:13 -07:00
2010-12-09 19:12:32 -08:00
struct Scsi_Host * bfad_scsi_host_alloc ( struct bfad_im_port_s * im_port ,
2009-09-23 17:46:15 -07:00
struct bfad_s * ) ;
2010-12-09 19:12:32 -08:00
bfa_status_t bfad_thread_workq ( struct bfad_s * bfad ) ;
void bfad_destroy_workq ( struct bfad_im_s * im ) ;
void bfad_fc_host_init ( struct bfad_im_port_s * im_port ) ;
void bfad_scsi_host_free ( struct bfad_s * bfad ,
2009-09-23 17:46:15 -07:00
struct bfad_im_port_s * im_port ) ;
2010-12-09 19:12:32 -08:00
void bfad_ramp_up_qdepth ( struct bfad_itnim_s * itnim ,
2009-09-23 17:46:15 -07:00
struct scsi_device * sdev ) ;
2010-12-09 19:12:32 -08:00
void bfad_handle_qfull ( struct bfad_itnim_s * itnim , struct scsi_device * sdev ) ;
struct bfad_itnim_s * bfad_get_itnim ( struct bfad_im_port_s * im_port , int id ) ;
2009-09-23 17:46:15 -07:00
extern struct scsi_host_template bfad_im_scsi_host_template ;
extern struct scsi_host_template bfad_im_vport_template ;
extern struct fc_function_template bfad_im_fc_function_template ;
2010-03-19 11:05:39 -07:00
extern struct fc_function_template bfad_im_vport_fc_function_template ;
2009-09-23 17:46:15 -07:00
extern struct scsi_transport_template * bfad_im_scsi_transport_template ;
2010-03-19 11:05:39 -07:00
extern struct scsi_transport_template * bfad_im_scsi_vport_transport_template ;
2009-09-23 17:46:15 -07:00
2010-09-15 11:50:55 -07:00
extern struct device_attribute * bfad_im_host_attrs [ ] ;
extern struct device_attribute * bfad_im_vport_attrs [ ] ;
irqreturn_t bfad_intx ( int irq , void * dev_id ) ;
2016-11-17 10:31:19 +01:00
int bfad_im_bsg_request ( struct bsg_job * job ) ;
int bfad_im_bsg_timeout ( struct bsg_job * job ) ;
2011-06-13 15:55:11 -07:00
2011-12-20 18:58:32 -08:00
/*
* Macro to set the SCSI device sdev_bflags - sdev_bflags are used by the
* SCSI mid - layer to choose LUN Scanning mode REPORT_LUNS vs . Sequential Scan
*
* Internally iterate ' s over all the ITNIM ' s part of the im_port & set ' s the
* sdev_bflags for the scsi_device associated with LUN # 0.
*/
# define bfad_reset_sdev_bflags(__im_port, __lunmask_cfg) do { \
struct scsi_device * __sdev = NULL ; \
struct bfad_itnim_s * __itnim = NULL ; \
u32 scan_flags = BLIST_NOREPORTLUN | BLIST_SPARSELUN ; \
list_for_each_entry ( __itnim , & ( ( __im_port ) - > itnim_mapped_list ) , \
list_entry ) { \
__sdev = scsi_device_lookup ( ( __im_port ) - > shost , \
__itnim - > channel , \
__itnim - > scsi_tgt_id , 0 ) ; \
if ( __sdev ) { \
if ( ( __lunmask_cfg ) = = BFA_TRUE ) \
__sdev - > sdev_bflags | = scan_flags ; \
else \
__sdev - > sdev_bflags & = ~ scan_flags ; \
scsi_device_put ( __sdev ) ; \
} \
} \
} while ( 0 )
2009-09-23 17:46:15 -07:00
# endif