|
@@ -52,17 +52,20 @@ static struct scsi_transport_template *lpfc_transport_template = NULL;
|
|
|
static struct scsi_transport_template *lpfc_vport_transport_template = NULL;
|
|
|
static DEFINE_IDR(lpfc_hba_index);
|
|
|
|
|
|
-/************************************************************************/
|
|
|
-/* */
|
|
|
-/* lpfc_config_port_prep */
|
|
|
-/* This routine will do LPFC initialization prior to the */
|
|
|
-/* CONFIG_PORT mailbox command. This will be initialized */
|
|
|
-/* as a SLI layer callback routine. */
|
|
|
-/* This routine returns 0 on success or -ERESTART if it wants */
|
|
|
-/* the SLI layer to reset the HBA and try again. Any */
|
|
|
-/* other return value indicates an error. */
|
|
|
-/* */
|
|
|
-/************************************************************************/
|
|
|
+/**
|
|
|
+ * lpfc_config_port_prep: Perform lpfc initialization prior to config port.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This routine will do LPFC initialization prior to issuing the CONFIG_PORT
|
|
|
+ * mailbox command. It retrieves the revision information from the HBA and
|
|
|
+ * collects the Vital Product Data (VPD) about the HBA for preparing the
|
|
|
+ * configuration of the HBA.
|
|
|
+ *
|
|
|
+ * Return codes:
|
|
|
+ * 0 - success.
|
|
|
+ * -ERESTART - requests the SLI layer to reset the HBA and try again.
|
|
|
+ * Any other value - indicates an error.
|
|
|
+ **/
|
|
|
int
|
|
|
lpfc_config_port_prep(struct lpfc_hba *phba)
|
|
|
{
|
|
@@ -214,7 +217,16 @@ out_free_mbox:
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/* Completion handler for config async event mailbox command. */
|
|
|
+/**
|
|
|
+ * lpfc_config_async_cmpl: Completion handler for config async event mbox cmd.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ * @pmboxq: pointer to the driver internal queue element for mailbox command.
|
|
|
+ *
|
|
|
+ * This is the completion handler for driver's configuring asynchronous event
|
|
|
+ * mailbox command to the device. If the mailbox command returns successfully,
|
|
|
+ * it will set internal async event support flag to 1; otherwise, it will
|
|
|
+ * set internal async event support flag to 0.
|
|
|
+ **/
|
|
|
static void
|
|
|
lpfc_config_async_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
|
|
|
{
|
|
@@ -226,16 +238,19 @@ lpfc_config_async_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
-/************************************************************************/
|
|
|
-/* */
|
|
|
-/* lpfc_config_port_post */
|
|
|
-/* This routine will do LPFC initialization after the */
|
|
|
-/* CONFIG_PORT mailbox command. This will be initialized */
|
|
|
-/* as a SLI layer callback routine. */
|
|
|
-/* This routine returns 0 on success. Any other return value */
|
|
|
-/* indicates an error. */
|
|
|
-/* */
|
|
|
-/************************************************************************/
|
|
|
+/**
|
|
|
+ * lpfc_config_port_post: Perform lpfc initialization after config port.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This routine will do LPFC initialization after the CONFIG_PORT mailbox
|
|
|
+ * command call. It performs all internal resource and state setups on the
|
|
|
+ * port: post IOCB buffers, enable appropriate host interrupt attentions,
|
|
|
+ * ELS ring timers, etc.
|
|
|
+ *
|
|
|
+ * Return codes
|
|
|
+ * 0 - success.
|
|
|
+ * Any other value - error.
|
|
|
+ **/
|
|
|
int
|
|
|
lpfc_config_port_post(struct lpfc_hba *phba)
|
|
|
{
|
|
@@ -450,16 +465,17 @@ lpfc_config_port_post(struct lpfc_hba *phba)
|
|
|
return (0);
|
|
|
}
|
|
|
|
|
|
-/************************************************************************/
|
|
|
-/* */
|
|
|
-/* lpfc_hba_down_prep */
|
|
|
-/* This routine will do LPFC uninitialization before the */
|
|
|
-/* HBA is reset when bringing down the SLI Layer. This will be */
|
|
|
-/* initialized as a SLI layer callback routine. */
|
|
|
-/* This routine returns 0 on success. Any other return value */
|
|
|
-/* indicates an error. */
|
|
|
-/* */
|
|
|
-/************************************************************************/
|
|
|
+/**
|
|
|
+ * lpfc_hba_down_prep: Perform lpfc uninitialization prior to HBA reset.
|
|
|
+ * @phba: pointer to lpfc HBA data structure.
|
|
|
+ *
|
|
|
+ * This routine will do LPFC uninitialization before the HBA is reset when
|
|
|
+ * bringing down the SLI Layer.
|
|
|
+ *
|
|
|
+ * Return codes
|
|
|
+ * 0 - success.
|
|
|
+ * Any other value - error.
|
|
|
+ **/
|
|
|
int
|
|
|
lpfc_hba_down_prep(struct lpfc_hba *phba)
|
|
|
{
|
|
@@ -481,15 +497,17 @@ lpfc_hba_down_prep(struct lpfc_hba *phba)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/************************************************************************/
|
|
|
-/* */
|
|
|
-/* lpfc_hba_down_post */
|
|
|
-/* This routine will do uninitialization after the HBA is reset */
|
|
|
-/* when bringing down the SLI Layer. */
|
|
|
-/* This routine returns 0 on success. Any other return value */
|
|
|
-/* indicates an error. */
|
|
|
-/* */
|
|
|
-/************************************************************************/
|
|
|
+/**
|
|
|
+ * lpfc_hba_down_post: Perform lpfc uninitialization after HBA reset.
|
|
|
+ * @phba: pointer to lpfc HBA data structure.
|
|
|
+ *
|
|
|
+ * This routine will do uninitialization after the HBA is reset when bring
|
|
|
+ * down the SLI Layer.
|
|
|
+ *
|
|
|
+ * Return codes
|
|
|
+ * 0 - sucess.
|
|
|
+ * Any other value - error.
|
|
|
+ **/
|
|
|
int
|
|
|
lpfc_hba_down_post(struct lpfc_hba *phba)
|
|
|
{
|
|
@@ -548,7 +566,18 @@ lpfc_hba_down_post(struct lpfc_hba *phba)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/* HBA heart beat timeout handler */
|
|
|
+/**
|
|
|
+ * lpfc_hb_timeout: The HBA-timer timeout handler.
|
|
|
+ * @ptr: unsigned long holds the pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This is the HBA-timer timeout handler registered to the lpfc driver. When
|
|
|
+ * this timer fires, a HBA timeout event shall be posted to the lpfc driver
|
|
|
+ * work-port-events bitmap and the worker thread is notified. This timeout
|
|
|
+ * event will be used by the worker thread to invoke the actual timeout
|
|
|
+ * handler routine, lpfc_hb_timeout_handler. Any periodical operations will
|
|
|
+ * be performed in the timeout handler and the HBA timeout event bit shall
|
|
|
+ * be cleared by the worker thread after it has taken the event bitmap out.
|
|
|
+ **/
|
|
|
static void
|
|
|
lpfc_hb_timeout(unsigned long ptr)
|
|
|
{
|
|
@@ -568,6 +597,22 @@ lpfc_hb_timeout(unsigned long ptr)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_hb_mbox_cmpl: The lpfc heart-beat mailbox command callback function.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ * @pmboxq: pointer to the driver internal queue element for mailbox command.
|
|
|
+ *
|
|
|
+ * This is the callback function to the lpfc heart-beat mailbox command.
|
|
|
+ * If configured, the lpfc driver issues the heart-beat mailbox command to
|
|
|
+ * the HBA every LPFC_HB_MBOX_INTERVAL (current 5) seconds. At the time the
|
|
|
+ * heart-beat mailbox command is issued, the driver shall set up heart-beat
|
|
|
+ * timeout timer to LPFC_HB_MBOX_TIMEOUT (current 30) seconds and marks
|
|
|
+ * heart-beat outstanding state. Once the mailbox command comes back and
|
|
|
+ * no error conditions detected, the heart-beat mailbox command timer is
|
|
|
+ * reset to LPFC_HB_MBOX_INTERVAL seconds and the heart-beat outstanding
|
|
|
+ * state is cleared for the next heart-beat. If the timer expired with the
|
|
|
+ * heart-beat outstanding state set, the driver will put the HBA offline.
|
|
|
+ **/
|
|
|
static void
|
|
|
lpfc_hb_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
|
|
|
{
|
|
@@ -586,6 +631,22 @@ lpfc_hb_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_hb_timeout_handler: The HBA-timer timeout handler.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This is the actual HBA-timer timeout handler to be invoked by the worker
|
|
|
+ * thread whenever the HBA timer fired and HBA-timeout event posted. This
|
|
|
+ * handler performs any periodic operations needed for the device. If such
|
|
|
+ * periodic event has already been attended to either in the interrupt handler
|
|
|
+ * or by processing slow-ring or fast-ring events within the HBA-timer
|
|
|
+ * timeout window (LPFC_HB_MBOX_INTERVAL), this handler just simply resets
|
|
|
+ * the timer for the next timeout period. If lpfc heart-beat mailbox command
|
|
|
+ * is configured and there is no heart-beat mailbox command outstanding, a
|
|
|
+ * heart-beat mailbox is issued and timer set properly. Otherwise, if there
|
|
|
+ * has been a heart-beat mailbox command outstanding, the HBA shall be put
|
|
|
+ * to offline.
|
|
|
+ **/
|
|
|
void
|
|
|
lpfc_hb_timeout_handler(struct lpfc_hba *phba)
|
|
|
{
|
|
@@ -684,6 +745,13 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_offline_eratt: Bring lpfc offline on hardware error attention.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This routine is called to bring the HBA offline when HBA hardware error
|
|
|
+ * other than Port Error 6 has been detected.
|
|
|
+ **/
|
|
|
static void
|
|
|
lpfc_offline_eratt(struct lpfc_hba *phba)
|
|
|
{
|
|
@@ -704,14 +772,16 @@ lpfc_offline_eratt(struct lpfc_hba *phba)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
-/************************************************************************/
|
|
|
-/* */
|
|
|
-/* lpfc_handle_eratt */
|
|
|
-/* This routine will handle processing a Host Attention */
|
|
|
-/* Error Status event. This will be initialized */
|
|
|
-/* as a SLI layer callback routine. */
|
|
|
-/* */
|
|
|
-/************************************************************************/
|
|
|
+/**
|
|
|
+ * lpfc_handle_eratt: The HBA hardware error handler.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This routine is invoked to handle the following HBA hardware error
|
|
|
+ * conditions:
|
|
|
+ * 1 - HBA error attention interrupt
|
|
|
+ * 2 - DMA ring index out of range
|
|
|
+ * 3 - Mailbox command came back as unknown
|
|
|
+ **/
|
|
|
void
|
|
|
lpfc_handle_eratt(struct lpfc_hba *phba)
|
|
|
{
|
|
@@ -810,14 +880,13 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/************************************************************************/
|
|
|
-/* */
|
|
|
-/* lpfc_handle_latt */
|
|
|
-/* This routine will handle processing a Host Attention */
|
|
|
-/* Link Status event. This will be initialized */
|
|
|
-/* as a SLI layer callback routine. */
|
|
|
-/* */
|
|
|
-/************************************************************************/
|
|
|
+/**
|
|
|
+ * lpfc_handle_latt: The HBA link event handler.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This routine is invoked from the worker thread to handle a HBA host
|
|
|
+ * attention link event.
|
|
|
+ **/
|
|
|
void
|
|
|
lpfc_handle_latt(struct lpfc_hba *phba)
|
|
|
{
|
|
@@ -898,12 +967,20 @@ lpfc_handle_latt_err_exit:
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
-/************************************************************************/
|
|
|
-/* */
|
|
|
-/* lpfc_parse_vpd */
|
|
|
-/* This routine will parse the VPD data */
|
|
|
-/* */
|
|
|
-/************************************************************************/
|
|
|
+/**
|
|
|
+ * lpfc_parse_vpd: Parse VPD (Vital Product Data).
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ * @vpd: pointer to the vital product data.
|
|
|
+ * @len: length of the vital product data in bytes.
|
|
|
+ *
|
|
|
+ * This routine parses the Vital Product Data (VPD). The VPD is treated as
|
|
|
+ * an array of characters. In this routine, the ModelName, ProgramType, and
|
|
|
+ * ModelDesc, etc. fields of the phba data structure will be populated.
|
|
|
+ *
|
|
|
+ * Return codes
|
|
|
+ * 0 - pointer to the VPD passed in is NULL
|
|
|
+ * 1 - success
|
|
|
+ **/
|
|
|
static int
|
|
|
lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len)
|
|
|
{
|
|
@@ -1040,6 +1117,18 @@ lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len)
|
|
|
return(1);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_get_hba_model_desc: Retrieve HBA device model name and description.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ * @mdp: pointer to the data structure to hold the derived model name.
|
|
|
+ * @descp: pointer to the data structure to hold the derived description.
|
|
|
+ *
|
|
|
+ * This routine retrieves HBA's description based on its registered PCI device
|
|
|
+ * ID. The @descp passed into this function points to an array of 256 chars. It
|
|
|
+ * shall be returned with the model name, maximum speed, and the host bus type.
|
|
|
+ * The @mdp passed into this function points to an array of 80 chars. When the
|
|
|
+ * function returns, the @mdp will be filled with the model name.
|
|
|
+ **/
|
|
|
static void
|
|
|
lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
|
|
|
{
|
|
@@ -1190,14 +1279,18 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
|
|
|
m.name, m.max_speed, m.bus);
|
|
|
}
|
|
|
|
|
|
-/**************************************************/
|
|
|
-/* lpfc_post_buffer */
|
|
|
-/* */
|
|
|
-/* This routine will post count buffers to the */
|
|
|
-/* ring with the QUE_RING_BUF_CN command. This */
|
|
|
-/* allows 3 buffers / command to be posted. */
|
|
|
-/* Returns the number of buffers NOT posted. */
|
|
|
-/**************************************************/
|
|
|
+/**
|
|
|
+ * lpfc_post_buffer: Post IOCB(s) with DMA buffer descriptor(s) to a IOCB ring.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ * @pring: pointer to a IOCB ring.
|
|
|
+ * @cnt: the number of IOCBs to be posted to the IOCB ring.
|
|
|
+ *
|
|
|
+ * This routine posts a given number of IOCBs with the associated DMA buffer
|
|
|
+ * descriptors specified by the cnt argument to the given IOCB ring.
|
|
|
+ *
|
|
|
+ * Return codes
|
|
|
+ * The number of IOCBs NOT able to be posted to the IOCB ring.
|
|
|
+ **/
|
|
|
int
|
|
|
lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt)
|
|
|
{
|
|
@@ -1287,12 +1380,17 @@ lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/************************************************************************/
|
|
|
-/* */
|
|
|
-/* lpfc_post_rcv_buf */
|
|
|
-/* This routine post initial rcv buffers to the configured rings */
|
|
|
-/* */
|
|
|
-/************************************************************************/
|
|
|
+/**
|
|
|
+ * lpfc_post_rcv_buf: Post the initial receive IOCB buffers to ELS ring.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This routine posts initial receive IOCB buffers to the ELS ring. The
|
|
|
+ * current number of initial IOCB buffers specified by LPFC_BUF_RING0 is
|
|
|
+ * set to 64 IOCBs.
|
|
|
+ *
|
|
|
+ * Return codes
|
|
|
+ * 0 - success (currently always success)
|
|
|
+ **/
|
|
|
static int
|
|
|
lpfc_post_rcv_buf(struct lpfc_hba *phba)
|
|
|
{
|
|
@@ -1307,11 +1405,13 @@ lpfc_post_rcv_buf(struct lpfc_hba *phba)
|
|
|
|
|
|
#define S(N,V) (((V)<<(N))|((V)>>(32-(N))))
|
|
|
|
|
|
-/************************************************************************/
|
|
|
-/* */
|
|
|
-/* lpfc_sha_init */
|
|
|
-/* */
|
|
|
-/************************************************************************/
|
|
|
+/**
|
|
|
+ * lpfc_sha_init: Set up initial array of hash table entries.
|
|
|
+ * @HashResultPointer: pointer to an array as hash table.
|
|
|
+ *
|
|
|
+ * This routine sets up the initial values to the array of hash table entries
|
|
|
+ * for the LC HBAs.
|
|
|
+ **/
|
|
|
static void
|
|
|
lpfc_sha_init(uint32_t * HashResultPointer)
|
|
|
{
|
|
@@ -1322,11 +1422,16 @@ lpfc_sha_init(uint32_t * HashResultPointer)
|
|
|
HashResultPointer[4] = 0xC3D2E1F0;
|
|
|
}
|
|
|
|
|
|
-/************************************************************************/
|
|
|
-/* */
|
|
|
-/* lpfc_sha_iterate */
|
|
|
-/* */
|
|
|
-/************************************************************************/
|
|
|
+/**
|
|
|
+ * lpfc_sha_iterate: Iterate initial hash table with the working hash table.
|
|
|
+ * @HashResultPointer: pointer to an initial/result hash table.
|
|
|
+ * @HashWorkingPointer: pointer to an working hash table.
|
|
|
+ *
|
|
|
+ * This routine iterates an initial hash table pointed by @HashResultPointer
|
|
|
+ * with the values from the working hash table pointeed by @HashWorkingPointer.
|
|
|
+ * The results are putting back to the initial hash table, returned through
|
|
|
+ * the @HashResultPointer as the result hash table.
|
|
|
+ **/
|
|
|
static void
|
|
|
lpfc_sha_iterate(uint32_t * HashResultPointer, uint32_t * HashWorkingPointer)
|
|
|
{
|
|
@@ -1374,22 +1479,29 @@ lpfc_sha_iterate(uint32_t * HashResultPointer, uint32_t * HashWorkingPointer)
|
|
|
|
|
|
}
|
|
|
|
|
|
-/************************************************************************/
|
|
|
-/* */
|
|
|
-/* lpfc_challenge_key */
|
|
|
-/* */
|
|
|
-/************************************************************************/
|
|
|
+/**
|
|
|
+ * lpfc_challenge_key: Create challenge key based on WWPN of the HBA.
|
|
|
+ * @RandomChallenge: pointer to the entry of host challenge random number array.
|
|
|
+ * @HashWorking: pointer to the entry of the working hash array.
|
|
|
+ *
|
|
|
+ * This routine calculates the working hash array referred by @HashWorking
|
|
|
+ * from the challenge random numbers associated with the host, referred by
|
|
|
+ * @RandomChallenge. The result is put into the entry of the working hash
|
|
|
+ * array and returned by reference through @HashWorking.
|
|
|
+ **/
|
|
|
static void
|
|
|
lpfc_challenge_key(uint32_t * RandomChallenge, uint32_t * HashWorking)
|
|
|
{
|
|
|
*HashWorking = (*RandomChallenge ^ *HashWorking);
|
|
|
}
|
|
|
|
|
|
-/************************************************************************/
|
|
|
-/* */
|
|
|
-/* lpfc_hba_init */
|
|
|
-/* */
|
|
|
-/************************************************************************/
|
|
|
+/**
|
|
|
+ * lpfc_hba_init: Perform special handling for LC HBA initialization.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ * @hbainit: pointer to an array of unsigned 32-bit integers.
|
|
|
+ *
|
|
|
+ * This routine performs the special handling for LC HBA initialization.
|
|
|
+ **/
|
|
|
void
|
|
|
lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit)
|
|
|
{
|
|
@@ -1412,6 +1524,15 @@ lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit)
|
|
|
kfree(HashWorking);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_cleanup: Performs vport cleanups before deleting a vport.
|
|
|
+ * @vport: pointer to a virtual N_Port data structure.
|
|
|
+ *
|
|
|
+ * This routine performs the necessary cleanups before deleting the @vport.
|
|
|
+ * It invokes the discovery state machine to perform necessary state
|
|
|
+ * transitions and to release the ndlps associated with the @vport. Note,
|
|
|
+ * the physical port is treated as @vport 0.
|
|
|
+ **/
|
|
|
void
|
|
|
lpfc_cleanup(struct lpfc_vport *vport)
|
|
|
{
|
|
@@ -1498,6 +1619,14 @@ lpfc_cleanup(struct lpfc_vport *vport)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_stop_vport_timers: Stop all the timers associated with a vport.
|
|
|
+ * @vport: pointer to a virtual N_Port data structure.
|
|
|
+ *
|
|
|
+ * This routine stops all the timers associated with a @vport. This function
|
|
|
+ * is invoked before disabling or deleting a @vport. Note that the physical
|
|
|
+ * port is treated as @vport 0.
|
|
|
+ **/
|
|
|
void
|
|
|
lpfc_stop_vport_timers(struct lpfc_vport *vport)
|
|
|
{
|
|
@@ -1507,6 +1636,13 @@ lpfc_stop_vport_timers(struct lpfc_vport *vport)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_stop_phba_timers: Stop all the timers associated with an HBA.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This routine stops all the timers associated with a HBA. This function is
|
|
|
+ * invoked before either putting a HBA offline or unloading the driver.
|
|
|
+ **/
|
|
|
static void
|
|
|
lpfc_stop_phba_timers(struct lpfc_hba *phba)
|
|
|
{
|
|
@@ -1519,6 +1655,16 @@ lpfc_stop_phba_timers(struct lpfc_hba *phba)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_block_mgmt_io: Mark a HBA's management interface as blocked.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This routine marks a HBA's management interface as blocked. Once the HBA's
|
|
|
+ * management interface is marked as blocked, all the user space access to
|
|
|
+ * the HBA, whether they are from sysfs interface or libdfc interface will
|
|
|
+ * all be blocked. The HBA is set to block the management interface when the
|
|
|
+ * driver prepares the HBA interface for online or offline.
|
|
|
+ **/
|
|
|
static void
|
|
|
lpfc_block_mgmt_io(struct lpfc_hba * phba)
|
|
|
{
|
|
@@ -1529,6 +1675,18 @@ lpfc_block_mgmt_io(struct lpfc_hba * phba)
|
|
|
spin_unlock_irqrestore(&phba->hbalock, iflag);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_online: Initialize and bring a HBA online.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This routine initializes the HBA and brings a HBA online. During this
|
|
|
+ * process, the management interface is blocked to prevent user space access
|
|
|
+ * to the HBA interfering with the driver initialization.
|
|
|
+ *
|
|
|
+ * Return codes
|
|
|
+ * 0 - successful
|
|
|
+ * 1 - failed
|
|
|
+ **/
|
|
|
int
|
|
|
lpfc_online(struct lpfc_hba *phba)
|
|
|
{
|
|
@@ -1574,6 +1732,17 @@ lpfc_online(struct lpfc_hba *phba)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_unblock_mgmt_io: Mark a HBA's management interface to be not blocked.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This routine marks a HBA's management interface as not blocked. Once the
|
|
|
+ * HBA's management interface is marked as not blocked, all the user space
|
|
|
+ * access to the HBA, whether they are from sysfs interface or libdfc
|
|
|
+ * interface will be allowed. The HBA is set to block the management interface
|
|
|
+ * when the driver prepares the HBA interface for online or offline and then
|
|
|
+ * set to unblock the management interface afterwards.
|
|
|
+ **/
|
|
|
void
|
|
|
lpfc_unblock_mgmt_io(struct lpfc_hba * phba)
|
|
|
{
|
|
@@ -1584,6 +1753,14 @@ lpfc_unblock_mgmt_io(struct lpfc_hba * phba)
|
|
|
spin_unlock_irqrestore(&phba->hbalock, iflag);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_offline_prep: Prepare a HBA to be brought offline.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This routine is invoked to prepare a HBA to be brought offline. It performs
|
|
|
+ * unregistration login to all the nodes on all vports and flushes the mailbox
|
|
|
+ * queue to make it ready to be brought offline.
|
|
|
+ **/
|
|
|
void
|
|
|
lpfc_offline_prep(struct lpfc_hba * phba)
|
|
|
{
|
|
@@ -1633,6 +1810,14 @@ lpfc_offline_prep(struct lpfc_hba * phba)
|
|
|
lpfc_sli_flush_mbox_queue(phba);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_offline: Bring a HBA offline.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This routine actually brings a HBA offline. It stops all the timers
|
|
|
+ * associated with the HBA, brings down the SLI layer, and eventually
|
|
|
+ * marks the HBA as in offline state for the upper layer protocol.
|
|
|
+ **/
|
|
|
void
|
|
|
lpfc_offline(struct lpfc_hba *phba)
|
|
|
{
|
|
@@ -1670,12 +1855,17 @@ lpfc_offline(struct lpfc_hba *phba)
|
|
|
lpfc_destroy_vport_work_array(phba, vports);
|
|
|
}
|
|
|
|
|
|
-/******************************************************************************
|
|
|
-* Function name: lpfc_scsi_free
|
|
|
-*
|
|
|
-* Description: Called from lpfc_pci_remove_one free internal driver resources
|
|
|
-*
|
|
|
-******************************************************************************/
|
|
|
+/**
|
|
|
+ * lpfc_scsi_free: Free all the SCSI buffers and IOCBs from driver lists.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This routine is to free all the SCSI buffers and IOCBs from the driver
|
|
|
+ * list back to kernel. It is called from lpfc_pci_remove_one to free
|
|
|
+ * the internal resources before the device is removed from the system.
|
|
|
+ *
|
|
|
+ * Return codes
|
|
|
+ * 0 - successful (for now, it always returns 0)
|
|
|
+ **/
|
|
|
static int
|
|
|
lpfc_scsi_free(struct lpfc_hba *phba)
|
|
|
{
|
|
@@ -1704,6 +1894,22 @@ lpfc_scsi_free(struct lpfc_hba *phba)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_create_port: Create an FC port.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ * @instance: a unique integer ID to this FC port.
|
|
|
+ * @dev: pointer to the device data structure.
|
|
|
+ *
|
|
|
+ * This routine creates a FC port for the upper layer protocol. The FC port
|
|
|
+ * can be created on top of either a physical port or a virtual port provided
|
|
|
+ * by the HBA. This routine also allocates a SCSI host data structure (shost)
|
|
|
+ * and associates the FC port created before adding the shost into the SCSI
|
|
|
+ * layer.
|
|
|
+ *
|
|
|
+ * Return codes
|
|
|
+ * @vport - pointer to the virtual N_Port data structure.
|
|
|
+ * NULL - port create failed.
|
|
|
+ **/
|
|
|
struct lpfc_vport *
|
|
|
lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
|
|
|
{
|
|
@@ -1777,6 +1983,13 @@ out:
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * destroy_port: Destroy an FC port.
|
|
|
+ * @vport: pointer to an lpfc virtual N_Port data structure.
|
|
|
+ *
|
|
|
+ * This routine destroys a FC port from the upper layer protocol. All the
|
|
|
+ * resources associated with the port are released.
|
|
|
+ **/
|
|
|
void
|
|
|
destroy_port(struct lpfc_vport *vport)
|
|
|
{
|
|
@@ -1797,6 +2010,16 @@ destroy_port(struct lpfc_vport *vport)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_get_instance: Get a unique integer ID.
|
|
|
+ *
|
|
|
+ * This routine allocates a unique integer ID from lpfc_hba_index pool. It
|
|
|
+ * uses the kernel idr facility to perform the task.
|
|
|
+ *
|
|
|
+ * Return codes:
|
|
|
+ * instance - a unique integer ID allocated as the new instance.
|
|
|
+ * -1 - lpfc get instance failed.
|
|
|
+ **/
|
|
|
int
|
|
|
lpfc_get_instance(void)
|
|
|
{
|
|
@@ -1810,11 +2033,21 @@ lpfc_get_instance(void)
|
|
|
return instance;
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * Note: there is no scan_start function as adapter initialization
|
|
|
- * will have asynchronously kicked off the link initialization.
|
|
|
- */
|
|
|
-
|
|
|
+/**
|
|
|
+ * lpfc_scan_finished: method for SCSI layer to detect whether scan is done.
|
|
|
+ * @shost: pointer to SCSI host data structure.
|
|
|
+ * @time: elapsed time of the scan in jiffies.
|
|
|
+ *
|
|
|
+ * This routine is called by the SCSI layer with a SCSI host to determine
|
|
|
+ * whether the scan host is finished.
|
|
|
+ *
|
|
|
+ * Note: there is no scan_start function as adapter initialization will have
|
|
|
+ * asynchronously kicked off the link initialization.
|
|
|
+ *
|
|
|
+ * Return codes
|
|
|
+ * 0 - SCSI host scan is not over yet.
|
|
|
+ * 1 - SCSI host scan is over.
|
|
|
+ **/
|
|
|
int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time)
|
|
|
{
|
|
|
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
|
|
@@ -1858,6 +2091,13 @@ finished:
|
|
|
return stat;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_host_attrib_init: Initialize SCSI host attributes on a FC port.
|
|
|
+ * @shost: pointer to SCSI host data structure.
|
|
|
+ *
|
|
|
+ * This routine initializes a given SCSI host attributes on a FC port. The
|
|
|
+ * SCSI host can be either on top of a physical port or a virtual port.
|
|
|
+ **/
|
|
|
void lpfc_host_attrib_init(struct Scsi_Host *shost)
|
|
|
{
|
|
|
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
|
|
@@ -1906,6 +2146,25 @@ void lpfc_host_attrib_init(struct Scsi_Host *shost)
|
|
|
spin_unlock_irq(shost->host_lock);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_enable_msix: Enable MSI-X interrupt mode.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This routine is invoked to enable the MSI-X interrupt vectors. The kernel
|
|
|
+ * function pci_enable_msix() is called to enable the MSI-X vectors. Note that
|
|
|
+ * pci_enable_msix(), once invoked, enables either all or nothing, depending
|
|
|
+ * on the current availability of PCI vector resources. The device driver is
|
|
|
+ * responsible for calling the individual request_irq() to register each MSI-X
|
|
|
+ * vector with a interrupt handler, which is done in this function. Note that
|
|
|
+ * later when device is unloading, the driver should always call free_irq()
|
|
|
+ * on all MSI-X vectors it has done request_irq() on before calling
|
|
|
+ * pci_disable_msix(). Failure to do so results in a BUG_ON() and a device
|
|
|
+ * will be left with MSI-X enabled and leaks its vectors.
|
|
|
+ *
|
|
|
+ * Return codes
|
|
|
+ * 0 - sucessful
|
|
|
+ * other values - error
|
|
|
+ **/
|
|
|
static int
|
|
|
lpfc_enable_msix(struct lpfc_hba *phba)
|
|
|
{
|
|
@@ -1935,6 +2194,13 @@ lpfc_enable_msix(struct lpfc_hba *phba)
|
|
|
return error;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_disable_msix: Disable MSI-X interrupt mode.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ *
|
|
|
+ * This routine is invoked to release the MSI-X vectors and then disable the
|
|
|
+ * MSI-X interrupt mode.
|
|
|
+ **/
|
|
|
static void
|
|
|
lpfc_disable_msix(struct lpfc_hba *phba)
|
|
|
{
|
|
@@ -1942,6 +2208,23 @@ lpfc_disable_msix(struct lpfc_hba *phba)
|
|
|
pci_disable_msix(phba->pcidev);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_pci_probe_one: lpfc PCI probe func to register device to PCI subsystem.
|
|
|
+ * @pdev: pointer to PCI device
|
|
|
+ * @pid: pointer to PCI device identifier
|
|
|
+ *
|
|
|
+ * This routine is to be registered to the kernel's PCI subsystem. When an
|
|
|
+ * Emulex HBA is presented in PCI bus, the kernel PCI subsystem looks at
|
|
|
+ * PCI device-specific information of the device and driver to see if the
|
|
|
+ * driver state that it can support this kind of device. If the match is
|
|
|
+ * successful, the driver core invokes this routine. If this routine
|
|
|
+ * determines it can claim the HBA, it does all the initialization that it
|
|
|
+ * needs to do to handle the HBA properly.
|
|
|
+ *
|
|
|
+ * Return code
|
|
|
+ * 0 - driver can claim the device
|
|
|
+ * negative value - driver can not claim the device
|
|
|
+ **/
|
|
|
static int __devinit
|
|
|
lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
|
|
|
{
|
|
@@ -2262,6 +2545,14 @@ out:
|
|
|
return error;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_pci_remove_one: lpfc PCI func to unregister device from PCI subsystem.
|
|
|
+ * @pdev: pointer to PCI device
|
|
|
+ *
|
|
|
+ * This routine is to be registered to the kernel's PCI subsystem. When an
|
|
|
+ * Emulex HBA is removed from PCI bus. It perform all the necessary cleanup
|
|
|
+ * for the HBA device to be removed from the PCI subsystem properly.
|
|
|
+ **/
|
|
|
static void __devexit
|
|
|
lpfc_pci_remove_one(struct pci_dev *pdev)
|
|
|
{
|
|
@@ -2336,13 +2627,21 @@ lpfc_pci_remove_one(struct pci_dev *pdev)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * lpfc_io_error_detected - called when PCI error is detected
|
|
|
- * @pdev: Pointer to PCI device
|
|
|
- * @state: The current pci conneection state
|
|
|
+ * lpfc_io_error_detected: Driver method for handling PCI I/O error detected.
|
|
|
+ * @pdev: pointer to PCI device.
|
|
|
+ * @state: the current PCI connection state.
|
|
|
*
|
|
|
- * This function is called after a PCI bus error affecting
|
|
|
- * this device has been detected.
|
|
|
- */
|
|
|
+ * This routine is registered to the PCI subsystem for error handling. This
|
|
|
+ * function is called by the PCI subsystem after a PCI bus error affecting
|
|
|
+ * this device has been detected. When this function is invoked, it will
|
|
|
+ * need to stop all the I/Os and interrupt(s) to the device. Once that is
|
|
|
+ * done, it will return PCI_ERS_RESULT_NEED_RESET for the PCI subsystem to
|
|
|
+ * perform proper recovery as desired.
|
|
|
+ *
|
|
|
+ * Return codes
|
|
|
+ * PCI_ERS_RESULT_NEED_RESET - need to reset before recovery
|
|
|
+ * PCI_ERS_RESULT_DISCONNECT - device could not be recovered
|
|
|
+ **/
|
|
|
static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev,
|
|
|
pci_channel_state_t state)
|
|
|
{
|
|
@@ -2376,10 +2675,21 @@ static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev,
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * lpfc_io_slot_reset - called after the pci bus has been reset.
|
|
|
- * @pdev: Pointer to PCI device
|
|
|
+ * lpfc_io_slot_reset: Restart a PCI device from scratch.
|
|
|
+ * @pdev: pointer to PCI device.
|
|
|
+ *
|
|
|
+ * This routine is registered to the PCI subsystem for error handling. This is
|
|
|
+ * called after PCI bus has been reset to restart the PCI card from scratch,
|
|
|
+ * as if from a cold-boot. During the PCI subsystem error recovery, after the
|
|
|
+ * driver returns PCI_ERS_RESULT_NEED_RESET, the PCI subsystem will perform
|
|
|
+ * proper error recovery and then call this routine before calling the .resume
|
|
|
+ * method to recover the device. This function will initialize the HBA device,
|
|
|
+ * enable the interrupt, but it will just put the HBA to offline state without
|
|
|
+ * passing any I/O traffic.
|
|
|
*
|
|
|
- * Restart the card from scratch, as if from a cold-boot.
|
|
|
+ * Return codes
|
|
|
+ * PCI_ERS_RESULT_RECOVERED - the device has been recovered
|
|
|
+ * PCI_ERS_RESULT_DISCONNECT - device could not be recovered
|
|
|
*/
|
|
|
static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
|
|
|
{
|
|
@@ -2440,11 +2750,13 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * lpfc_io_resume - called when traffic can start flowing again.
|
|
|
- * @pdev: Pointer to PCI device
|
|
|
+ * lpfc_io_resume: Resume PCI I/O operation.
|
|
|
+ * @pdev: pointer to PCI device
|
|
|
*
|
|
|
- * This callback is called when the error recovery driver tells us that
|
|
|
- * its OK to resume normal operation.
|
|
|
+ * This routine is registered to the PCI subsystem for error handling. It is
|
|
|
+ * called when kernel error recovery tells the lpfc driver that it is ok to
|
|
|
+ * resume normal PCI operation after PCI bus error recovery. After this call,
|
|
|
+ * traffic can start to flow from this device again.
|
|
|
*/
|
|
|
static void lpfc_io_resume(struct pci_dev *pdev)
|
|
|
{
|
|
@@ -2540,6 +2852,18 @@ static struct pci_driver lpfc_driver = {
|
|
|
.err_handler = &lpfc_err_handler,
|
|
|
};
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_init: lpfc module initialization routine.
|
|
|
+ *
|
|
|
+ * This routine is to be invoked when the lpfc module is loaded into the
|
|
|
+ * kernel. The special kernel macro module_init() is used to indicate the
|
|
|
+ * role of this routine to the kernel as lpfc module entry point.
|
|
|
+ *
|
|
|
+ * Return codes
|
|
|
+ * 0 - successful
|
|
|
+ * -ENOMEM - FC attach transport failed
|
|
|
+ * all others - failed
|
|
|
+ */
|
|
|
static int __init
|
|
|
lpfc_init(void)
|
|
|
{
|
|
@@ -2573,6 +2897,13 @@ lpfc_init(void)
|
|
|
return error;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_exit: lpfc module removal routine.
|
|
|
+ *
|
|
|
+ * This routine is invoked when the lpfc module is removed from the kernel.
|
|
|
+ * The special kernel macro module_exit() is used to indicate the role of
|
|
|
+ * this routine to the kernel as lpfc module exit point.
|
|
|
+ */
|
|
|
static void __exit
|
|
|
lpfc_exit(void)
|
|
|
{
|