lpfc 8.2.8 : Add statistical reporting control and additional fc vendor events
Subsystems (2)
PATCH 14/15 lpfc 8.2.8 : Add statistical reporting control and additional fc vendor events
Added support for new sysfs attributes: lpfc_stat_data_ctrl and lpfc_max_scsicmpl_time. The attributes control statistical reporting of io load.
Added support for new fc vendor events for error reporting.
---
lpfc.h | 27 ++-- lpfc_attr.c | 343 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- lpfc_crtn.h | 6 lpfc_ct.c | 1 lpfc_debugfs.c | 1 lpfc_disc.h | 20 +++ lpfc_els.c | 114 ++++++++++++++++++ lpfc_hbadisc.c | 143 ++++++++++++++++++++++ lpfc_init.c | 22 +++ lpfc_mbox.c | 1 lpfc_mem.c | 1 lpfc_nl.h | 163 ++++++++++++++++++++++++++ lpfc_nportdisc.c | 1 lpfc_scsi.c | 279 ++++++++++++++++++++++++++++++++++++++++++++ lpfc_scsi.h | 4 lpfc_sli.c | 12 + lpfc_vport.c | 80 ++++++++++++ lpfc_vport.h | 4 18 files changed, 1207 insertions(+), 15 deletions(-)
drivers/scsi/lpfc/lpfc_attr.c +342 -1
@@ -32,6 +32,7 @@#include "lpfc_hw.h" #include "lpfc_sli.h" +#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h"
@@ -2183,6 +2184,335 @@ lpfc_param_store(topology) static DEVICE_ATTR(lpfc_topology, S_IRUGO | S_IWUSR, lpfc_topology_show, lpfc_topology_store); + +/** +* lpfc_stat_data_ctrl_store: write call back for lpfc_stat_data_ctrl +* sysfs file. +* @dev: Pointer to class device. +* @buf: Data buffer. +* @count: Size of the data buffer. +* +* This function get called when an user write to the lpfc_stat_data_ctrl +* sysfs file. This function parse the command written to the sysfs file +* and take appropriate action. These commands are used for controlling +* driver statistical data collection. +* Following are the command this function handles. +* +* setbucket <bucket_type> <base> <step> +* = Set the latency buckets. +* destroybucket = destroy all the buckets. +* start = start data collection +* stop = stop data collection +* reset = reset the collected data +**/ +static ssize_t +lpfc_stat_data_ctrl_store (struct device *dev,struct device_attribute *attr, +const char *buf,size_t count) +{ +struct Scsi_Host *shost =class_to_shost (dev); +struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; +struct lpfc_hba *phba = vport->phba; +#define LPFC_MAX_DATA_CTRL_LEN 1024 +static char bucket_data[LPFC_MAX_DATA_CTRL_LEN ]; +unsigned long i; +char *str_ptr, *token; +struct lpfc_vport **vports; +struct Scsi_Host *v_shost; +char *bucket_type_str, *base_str, *step_str; +unsigned long base, step, bucket_type; + +if (!strncmp (buf,"setbucket" ,strlen ("setbucket" ))) { +if (strlen (buf) >LPFC_MAX_DATA_CTRL_LEN ) +return -EINVAL ; + +strcpy (bucket_data, buf); + str_ptr = &bucket_data[0 ]; +/* Ignore this token - this is command token */ + token =strsep (&str_ptr,"\t " ); +if (!token) +return -EINVAL ; + + bucket_type_str =strsep (&str_ptr,"\t " ); +if (!bucket_type_str) +return -EINVAL ; + +if (!strncmp (bucket_type_str,"linear" ,strlen ("linear" ))) + bucket_type =LPFC_LINEAR_BUCKET ; +else if (!strncmp (bucket_type_str,"power2" ,strlen ("power2" ))) + bucket_type =LPFC_POWER2_BUCKET ; +else +return -EINVAL ; + + base_str =strsep (&str_ptr,"\t " ); +if (!base_str) +return -EINVAL ; + base =simple_strtoul (base_str,NULL ,0 ); + + step_str =strsep (&str_ptr,"\t " ); +if (!step_str) +return -EINVAL ; + step =simple_strtoul (step_str,NULL ,0 ); +if (!step) +return -EINVAL ; + +/* Block the data collection for every vport */ + vports =lpfc_create_vport_work_array (phba); +if (vports ==NULL ) +return -ENOMEM ; + +for (i =0 ; i <= phba->max_vpi && vports[i] !=NULL ; i++) { + v_shost =lpfc_shost_from_vport (vports[i]); +spin_lock_irq (v_shost->host_lock); +/* Block and reset data collection */ + vports[i]->stat_data_blocked =1 ; +if (vports[i]->stat_data_enabled) +lpfc_vport_reset_stat_data (vports[i]); +spin_unlock_irq (v_shost->host_lock); + } + +/* Set the bucket attributes */ + phba->bucket_type = bucket_type; + phba->bucket_base = base; + phba->bucket_step = step; + +for (i =0 ; i <= phba->max_vpi && vports[i] !=NULL ; i++) { + v_shost =lpfc_shost_from_vport (vports[i]); + +/* Unblock data collection */ +spin_lock_irq (v_shost->host_lock); + vports[i]->stat_data_blocked =0 ; +spin_unlock_irq (v_shost->host_lock); + } +lpfc_destroy_vport_work_array (phba, vports); +return strlen (buf); + } + +if (!strncmp (buf,"destroybucket" ,strlen ("destroybucket" ))) { + vports =lpfc_create_vport_work_array (phba); +if (vports ==NULL ) +return -ENOMEM ; + +for (i =0 ; i <= phba->max_vpi && vports[i] !=NULL ; i++) { + v_shost =lpfc_shost_from_vport (vports[i]); +spin_lock_irq (shost->host_lock); + vports[i]->stat_data_blocked =1 ; +lpfc_free_bucket (vport); + vport->stat_data_enabled =0 ; + vports[i]->stat_data_blocked =0 ; +spin_unlock_irq (shost->host_lock); + } +lpfc_destroy_vport_work_array (phba, vports); + phba->bucket_type =LPFC_NO_BUCKET ; + phba->bucket_base =0 ; + phba->bucket_step =0 ; +return strlen (buf); + } + +if (!strncmp (buf,"start" ,strlen ("start" ))) { +/* If no buckets configured return error */ +if (phba->bucket_type ==LPFC_NO_BUCKET ) +return -EINVAL ; +spin_lock_irq (shost->host_lock); +if (vport->stat_data_enabled) { +spin_unlock_irq (shost->host_lock); +return strlen (buf); + } +lpfc_alloc_bucket (vport); + vport->stat_data_enabled =1 ; +spin_unlock_irq (shost->host_lock); +return strlen (buf); + } + +if (!strncmp (buf,"stop" ,strlen ("stop" ))) { +spin_lock_irq (shost->host_lock); +if (vport->stat_data_enabled ==0 ) { +spin_unlock_irq (shost->host_lock); +return strlen (buf); + } +lpfc_free_bucket (vport); + vport->stat_data_enabled =0 ; +spin_unlock_irq (shost->host_lock); +return strlen (buf); + } + +if (!strncmp (buf,"reset" ,strlen ("reset" ))) { +if ((phba->bucket_type ==LPFC_NO_BUCKET ) + || !vport->stat_data_enabled) +return strlen (buf); +spin_lock_irq (shost->host_lock); + vport->stat_data_blocked =1 ; +lpfc_vport_reset_stat_data (vport); + vport->stat_data_blocked =0 ; +spin_unlock_irq (shost->host_lock); +return strlen (buf); + } +return -EINVAL ; +} + + +/** +* lpfc_stat_data_ctrl_show: Read callback function for +* lpfc_stat_data_ctrl sysfs file. +* @dev: Pointer to class device object. +* @buf: Data buffer. +* +* This function is the read call back function for +* lpfc_stat_data_ctrl sysfs file. This function report the +* current statistical data collection state. +**/ +static ssize_t +lpfc_stat_data_ctrl_show (struct device *dev,struct device_attribute *attr, +char *buf) +{ +struct Scsi_Host *shost =class_to_shost (dev); +struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; +struct lpfc_hba *phba = vport->phba; +int index =0 ; +int i; +char *bucket_type; +unsigned long bucket_value; + +switch (phba->bucket_type) { +case LPFC_LINEAR_BUCKET : + bucket_type ="linear" ; +break ; +case LPFC_POWER2_BUCKET : + bucket_type ="power2" ; +break ; +default : + bucket_type ="No Bucket" ; +break ; + } + +sprintf (&buf[index],"Statistical Data enabled :%d, " +"blocked :%d, Bucket type :%s, Bucket base :%d," +" Bucket step :%d\nLatency Ranges :" , + vport->stat_data_enabled, vport->stat_data_blocked, + bucket_type, phba->bucket_base, phba->bucket_step); + index =strlen (buf); +if (phba->bucket_type !=LPFC_NO_BUCKET ) { +for (i =0 ; i <LPFC_MAX_BUCKET_COUNT ; i++) { +if (phba->bucket_type ==LPFC_LINEAR_BUCKET ) + bucket_value = phba->bucket_base + + phba->bucket_step * i; +else + bucket_value = phba->bucket_base + + (1 << i) * phba->bucket_step; + +if (index +10 >PAGE_SIZE ) +break ; +sprintf (&buf[index],"%08ld " , bucket_value); + index =strlen (buf); + } + } +sprintf (&buf[index],"\n" ); +return strlen (buf); +} + +/* +* Sysfs attribute to control the statistical data collection. +*/ +static DEVICE_ATTR(lpfc_stat_data_ctrl, S_IRUGO | S_IWUSR, + lpfc_stat_data_ctrl_show, lpfc_stat_data_ctrl_store); + +/* +* lpfc_drvr_stat_data: sysfs attr to get driver statistical data. +*/ + +/* +* Each Bucket takes 11 characters and 1 new line + 17 bytes WWN +* for each target. +*/ +#define STAT_DATA_SIZE_PER_TARGET (NUM_BUCKETS ) ((NUM_BUCKETS) * 11 + 18) +#define MAX_STAT_DATA_SIZE_PER_TARGET \ + STAT_DATA_SIZE_PER_TARGET(LPFC_MAX_BUCKET_COUNT) + + +/** +* sysfs_drvr_stat_data_read: Read callback function for lpfc_drvr_stat_data +* sysfs attribute. +* @kobj: Pointer to the kernel object +* @bin_attr: Attribute object +* @buff: Buffer pointer +* @off: File offset +* @count: Buffer size +* +* This function is the read call back function for lpfc_drvr_stat_data +* sysfs file. This function export the statistical data to user +* applications. +**/ +static ssize_t +sysfs_drvr_stat_data_read (struct kobject *kobj,struct bin_attribute *bin_attr, +char *buf,loff_t off,size_t count) +{ + struct device *dev = container_of(kobj, struct device, + kobj); +struct Scsi_Host *shost =class_to_shost (dev); +struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; +struct lpfc_hba *phba = vport->phba; +int i =0 , index =0 ; +unsigned long nport_index; +struct lpfc_nodelist *ndlp =NULL ; + nport_index = (unsigned long )off / +MAX_STAT_DATA_SIZE_PER_TARGET ; + +if (!vport->stat_data_enabled || vport->stat_data_blocked + || (phba->bucket_type ==LPFC_NO_BUCKET )) +return 0 ; + +spin_lock_irq (shost->host_lock); +list_for_each_entry (ndlp, &vport->fc_nodes, nlp_listp) { +if (!NLP_CHK_NODE_ACT (ndlp) || !ndlp->lat_data) +continue ; + +if (nport_index >0 ) { + nport_index--; +continue ; + } + +if ((index +MAX_STAT_DATA_SIZE_PER_TARGET ) + > count) +break ; + +if (!ndlp->lat_data) +continue ; + +/* Print the WWN */ +sprintf (&buf[index],"%02x%02x%02x%02x%02x%02x%02x%02x:" , + ndlp->nlp_portname.u.wwn[0 ], + ndlp->nlp_portname.u.wwn[1 ], + ndlp->nlp_portname.u.wwn[2 ], + ndlp->nlp_portname.u.wwn[3 ], + ndlp->nlp_portname.u.wwn[4 ], + ndlp->nlp_portname.u.wwn[5 ], + ndlp->nlp_portname.u.wwn[6 ], + ndlp->nlp_portname.u.wwn[7 ]); + + index =strlen (buf); + +for (i =0 ; i <LPFC_MAX_BUCKET_COUNT ; i++) { +sprintf (&buf[index],"%010u," , + ndlp->lat_data[i].cmd_count); + index =strlen (buf); + } +sprintf (&buf[index],"\n" ); + index =strlen (buf); + } +spin_unlock_irq (shost->host_lock); +return index; +} + +static struct bin_attribute sysfs_drvr_stat_data_attr = { + .attr = { + .name ="lpfc_drvr_stat_data" , + .mode =S_IRUSR , + .owner =THIS_MODULE , + }, + .size =LPFC_MAX_TARGET *MAX_STAT_DATA_SIZE_PER_TARGET , + .read = sysfs_drvr_stat_data_read, + .write =NULL , +}; +/* # lpfc_link_speed: Link speed selection for initializing the Fibre Channel # connection.
@@ -2502,6 +2832,7 @@ struct device_attribute *lpfc_hba_attrs[ &dev_attr_lpfc_enable_hba_heartbeat, &dev_attr_lpfc_sg_seg_cnt, &dev_attr_lpfc_max_scsicmpl_time, + &dev_attr_lpfc_stat_data_ctrl, NULL, };
@@ -2524,6 +2855,8 @@ struct device_attribute *lpfc_vport_attr &dev_attr_nport_evt_cnt, &dev_attr_npiv_info, &dev_attr_lpfc_enable_da_id, + &dev_attr_lpfc_max_scsicmpl_time, + &dev_attr_lpfc_stat_data_ctrl, NULL, };
@@ -2958,7 +3291,14 @@ lpfc_alloc_sysfs_attr(struct lpfc_vportif (error) goto out_remove_ctlreg_attr; + error =sysfs_create_bin_file (&shost->shost_dev.kobj, + &sysfs_drvr_stat_data_attr); +if (error) + goto out_remove_mbox_attr; +return 0 ; +out_remove_mbox_attr: +sysfs_remove_bin_file (&shost->shost_dev.kobj, &sysfs_mbox_attr); out_remove_ctlreg_attr:sysfs_remove_bin_file (&shost->shost_dev.kobj, &sysfs_ctlreg_attr); out:
@@ -2973,7 +3313,8 @@ void lpfc_free_sysfs_attr(struct lpfc_vport *vport) {struct Scsi_Host *shost =lpfc_shost_from_vport (vport); - +sysfs_remove_bin_file (&shost->shost_dev.kobj, + &sysfs_drvr_stat_data_attr);sysfs_remove_bin_file (&shost->shost_dev.kobj, &sysfs_mbox_attr);sysfs_remove_bin_file (&shost->shost_dev.kobj, &sysfs_ctlreg_attr); }
drivers/scsi/lpfc/lpfc_crtn.h +6 -0
@@ -294,6 +294,12 @@ void lpfc_ramp_down_queue_handler(structvoid lpfc_ramp_up_queue_handler (struct lpfc_hba *);void lpfc_scsi_dev_block (struct lpfc_hba *); +void +lpfc_send_els_failure_event (struct lpfc_hba *,struct lpfc_iocbq *, +struct lpfc_iocbq *); +struct lpfc_fast_path_event *lpfc_alloc_fast_evt (struct lpfc_hba *); +void lpfc_free_fast_evt (struct lpfc_hba *,struct lpfc_fast_path_event *); +#define ScsiResult (host_code, scsi_code) (((host_code) << 16) | scsi_code)#define HBA_EVENT_RSCN 5#define HBA_EVENT_LINK_UP 2
drivers/scsi/lpfc/lpfc_ct.c +1 -0
@@ -34,6 +34,7 @@#include "lpfc_hw.h" #include "lpfc_sli.h" +#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h"
drivers/scsi/lpfc/lpfc_debugfs.c +1 -0
@@ -36,6 +36,7 @@#include "lpfc_hw.h" #include "lpfc_sli.h" +#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h"
drivers/scsi/lpfc/lpfc_disc.h +20 -0
@@ -37,6 +37,7 @@ enum lpfc_work_type {LPFC_EVT_KILL ,LPFC_EVT_ELS_RETRY ,LPFC_EVT_DEV_LOSS , + LPFC_EVT_FASTPATH_MGMT_EVT, };/* structure used to queue event to the discovery tasklet */
@@ -47,6 +48,24 @@ struct lpfc_work_evt {enum lpfc_work_type evt; }; +struct lpfc_scsi_check_condition_event ; +struct lpfc_scsi_varqueuedepth_event ; +struct lpfc_scsi_event_header ; +struct lpfc_fabric_event_header ; +struct lpfc_fcprdchkerr_event ; + +/* structure used for sending events from fast path */ +struct lpfc_fast_path_event { +struct lpfc_work_evt work_evt; +struct lpfc_vport *vport; +union { +struct lpfc_scsi_check_condition_event check_cond_evt; +struct lpfc_scsi_varqueuedepth_event queue_depth_evt; +struct lpfc_scsi_event_header scsi_evt; +struct lpfc_fabric_event_header fabric_evt; +struct lpfc_fcprdchkerr_event read_check_error; + } un; +};struct lpfc_nodelist {struct list_head nlp_listp;
@@ -91,6 +110,7 @@ struct lpfc_nodelist {atomic_t cmd_pending;uint32_t cmd_qdepth;unsigned long last_change_time; +struct lpfc_scsicmd_bkt *lat_data;/* Latency data */ };/* Defines for nlp_flag (uint32) */
drivers/scsi/lpfc/lpfc_els.c +114 -0
144 lines not on this page · raw message
drivers/scsi/lpfc/lpfc.h +15 -12
@@ -40,6 +40,8 @@ struct lpfc_sli2_slim;#define LPFC_MIN_TGT_QDEPTH 100#define LPFC_MAX_TGT_QDEPTH 0xFFFF +#define LPFC_MAX_BUCKET_COUNT 20/* Maximum no. of buckets for stat data +collection. */ /* * Following time intervals are used of adjusting SCSI device * queue depths when there are driver resource error or Firmware
@@ -381,6 +383,8 @@ struct lpfc_vport {struct lpfc_debugfs_trc *disc_trc;atomic_t disc_trc_cnt;#endif +uint8_t stat_data_enabled; +uint8_t stat_data_blocked; };struct hbq_s {
@@ -641,6 +645,17 @@ struct lpfc_hba {uint32_t buffer_tag_count;int wait_4_mlo_maint_flg;wait_queue_head_t wait_4_mlo_m_q; +/* data structure used for latency data collection */ +#define LPFC_NO_BUCKET 0 +#define LPFC_LINEAR_BUCKET 1 +#define LPFC_POWER2_BUCKET 2 +uint8_t bucket_type; +uint32_t bucket_base; +uint32_t bucket_step; + +/* Maximum number of events that can be outstanding at any time*/ +#define LPFC_MAX_EVT_COUNT 512 +atomic_t fast_event_count; }; static inline struct Scsi_Host *
@@ -699,15 +714,3 @@ lpfc_sli_read_hs(struct lpfc_hba *phba)return ; } -#define FC_REG_DUMP_EVENT 0x10/* Register for Dump events */ -#define FC_REG_TEMPERATURE_EVENT 0x20/* Register for temperature -event */ - -struct temp_event { -uint32_t event_type; -uint32_t event_code; -uint32_t data; -}; -#define LPFC_CRIT_TEMP 0x1 -#define LPFC_THRESHOLD_TEMP 0x2 -#define LPFC_NORMAL_TEMP 0x3
drivers/scsi/lpfc/lpfc_hbadisc.c +142 -1
174 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_init.c +22 -0
@@ -36,6 +36,7 @@#include "lpfc_hw.h" #include "lpfc_sli.h" +#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h"
@@ -815,6 +816,7 @@ lpfc_handle_eratt(struct lpfc_hba *phba)unsigned long temperature;struct temp_event temp_event_data;struct Scsi_Host *shost; +struct lpfc_board_event_header board_event;/* If the pci channel is offline, ignore possible errors, * since we cannot communicate with the pci card anyway. */
@@ -824,6 +826,16 @@ lpfc_handle_eratt(struct lpfc_hba *phba)if (!phba->cfg_enable_hba_reset)return ; +/* Send an internal error event to mgmt application */ + board_event.event_type =FC_REG_BOARD_EVENT ; + board_event.subcategory =LPFC_EVENT_PORTINTERR ; + shost =lpfc_shost_from_vport (phba->pport); +fc_host_post_vendor_event (shost,fc_get_event_number (), +sizeof (board_event), + (char *) &board_event, +SCSI_NL_VID_TYPE_PCI + |PCI_VENDOR_ID_EMULEX ); +if (phba->work_hs &HS_FFER6 ) {/* Re-establishing Link */ lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
@@ -2345,6 +2357,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev,int i, hbq_count;uint16_t iotag;int bars =pci_select_bars (pdev,IORESOURCE_MEM ); +struct lpfc_adapter_event_header adapter_event;if (pci_enable_device_mem (pdev)) goto out;
@@ -2355,6 +2368,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev,if (!phba) goto out_release_regions; +atomic_set (&phba->fast_event_count,0 );spin_lock_init (&phba->hbalock);/* Initialize ndlp management spinlock */
@@ -2626,6 +2640,14 @@ lpfc_pci_probe_one(struct pci_dev *pdev,lpfc_printf_log (phba,KERN_INFO ,LOG_INIT ,"0428 Perform SCSI scan\n" ); +/* Send board arrival event to upper layer */ + adapter_event.event_type =FC_REG_ADAPTER_EVENT ; + adapter_event.subcategory =LPFC_EVENT_ARRIVAL ; +fc_host_post_vendor_event (shost,fc_get_event_number (), +sizeof (adapter_event), + (char *) &adapter_event, +SCSI_NL_VID_TYPE_PCI |PCI_VENDOR_ID_EMULEX ); +scsi_scan_host (shost);return 0 ;
drivers/scsi/lpfc/lpfc_mbox.c +1 -0
@@ -30,6 +30,7 @@#include "lpfc_hw.h" #include "lpfc_sli.h" +#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h"
drivers/scsi/lpfc/lpfc_mem.c +1 -0
@@ -30,6 +30,7 @@#include "lpfc_hw.h" #include "lpfc_sli.h" +#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h"
drivers/scsi/lpfc/lpfc_nl.h +163 -0
163 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_nportdisc.c +1 -0
@@ -30,6 +30,7 @@#include "lpfc_hw.h" #include "lpfc_sli.h" +#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h"
drivers/scsi/lpfc/lpfc_scsi.c +278 -1
395 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_scsi.h +4 -0
@@ -107,6 +107,10 @@ struct fcp_cmnd { }; +struct lpfc_scsicmd_bkt { +uint32_t cmd_count; +}; +struct lpfc_scsi_buf {struct list_head list;struct scsi_cmnd *pCmd;
drivers/scsi/lpfc/lpfc_sli.c +12 -0
@@ -32,6 +32,7 @@#include "lpfc_hw.h" #include "lpfc_sli.h" +#include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc_scsi.h" #include "lpfc.h"
@@ -1611,6 +1612,17 @@ lpfc_sli_process_sol_iocb(struct lpfc_hbif (cmdiocbp) {if (cmdiocbp->iocb_cmpl) {/* +* If an ELS command failed send an event to mgmt +* application. +*/ +if (saveq->iocb.ulpStatus && + (pring->ringno ==LPFC_ELS_RING ) && + (cmdiocbp->iocb.ulpCommand == +CMD_ELS_REQUEST64_CR )) +lpfc_send_els_failure_event (phba, + cmdiocbp, saveq); + +/* * Post all ELS completions to the worker thread. * All other are passed to the completion callback. */
drivers/scsi/lpfc/lpfc_vport.c +80 -0
89 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_vport.h +4 -0
@@ -112,4 +112,8 @@ struct vport_cmd_tag {void lpfc_vport_set_state (struct lpfc_vport *vport,enum fc_vport_state new_state); +void lpfc_vport_reset_stat_data (struct lpfc_vport *); +void lpfc_alloc_bucket (struct lpfc_vport *); +void lpfc_free_bucket (struct lpfc_vport *); +#endif /* H_LPFC_VPORT */
James Bottomley
maintainerQuoted 5 lines · James Smart
Added support for new sysfs attributes:
lpfc_stat_data_ctrlandlpfc_max_scsicmpl_time. The attributes control statistical reporting of io load.Added support for new fc vendor events for error reporting.
Had to drop this too ... it's giving a compile error because it's using a structure member introduced by 12/15
James
Ok - I'll pull your scsi-misc-2.6 tree tomorrow early am and recut the patches.
-- james s
Quoted 14 lines · James Bottomley
Quoted 5 lines · James Smart
Added support for new sysfs attributes:
lpfc_stat_data_ctrlandlpfc_max_scsicmpl_time. The attributes control statistical reporting of io load.Added support for new fc vendor events for error reporting.
Had to drop this too ... it's giving a compile error because it's using a structure member introduced by 12/15
James
James Bottomley
maintainerQuoted 2 lines · James Smart
Ok - I'll pull your scsi-misc-2.6 tree tomorrow early am and recut the patches.
Thanks. The rest seems to be functioning OK independently of those two.
James