Commit e30d1756 authored by Madhuranath Iyengar's avatar Madhuranath Iyengar Committed by James Bottomley

[SCSI] qla2xxx: Addition of shutdown callback handler.

This patch adds a shutdown handler to qla2xxx driver to make sure that all
DMA and firmware activities are stopped, and any associated driver resources
are released. The need for this handler arose when executing kexec in specific
environments caused the data of the 2nd kernel to be corrupted, due to DMA
activities.
Signed-off-by: default avatarMadhuranath Iyengar <Madhu.Iyengar@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 339aa70e
......@@ -1344,6 +1344,13 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
qla_printk(KERN_WARNING, ha, "Unable to allocate (%d KB) for "
"firmware dump!!!\n", dump_size / 1024);
if (ha->fce) {
dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce,
ha->fce_dma);
ha->fce = NULL;
ha->fce_dma = 0;
}
if (ha->eft) {
dma_free_coherent(&ha->pdev->dev, eft_size, ha->eft,
ha->eft_dma);
......
......@@ -260,6 +260,7 @@ static void qla2x00_rst_aen(scsi_qla_host_t *);
static int qla2x00_mem_alloc(struct qla_hw_data *, uint16_t, uint16_t,
struct req_que **, struct rsp_que **);
static void qla2x00_free_fw_dump(struct qla_hw_data *);
static void qla2x00_mem_free(struct qla_hw_data *);
static void qla2x00_sp_free_dma(srb_t *);
......@@ -2341,6 +2342,42 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
return ret;
}
static void
qla2x00_shutdown(struct pci_dev *pdev)
{
scsi_qla_host_t *vha;
struct qla_hw_data *ha;
vha = pci_get_drvdata(pdev);
ha = vha->hw;
/* Turn-off FCE trace */
if (ha->flags.fce_enabled) {
qla2x00_disable_fce_trace(vha, NULL, NULL);
ha->flags.fce_enabled = 0;
}
/* Turn-off EFT trace */
if (ha->eft)
qla2x00_disable_eft_trace(vha);
/* Stop currently executing firmware. */
qla2x00_try_to_stop_firmware(vha);
/* Turn adapter off line */
vha->flags.online = 0;
/* turn-off interrupts on the card */
if (ha->interrupts_on) {
vha->flags.init_done = 0;
ha->isp_ops->disable_intrs(ha);
}
qla2x00_free_irqs(vha);
qla2x00_free_fw_dump(ha);
}
static void
qla2x00_remove_one(struct pci_dev *pdev)
{
......@@ -2830,18 +2867,15 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
}
/*
* qla2x00_mem_free
* Frees all adapter allocated memory.
* qla2x00_free_fw_dump
* Frees fw dump stuff.
*
* Input:
* ha = adapter block pointer.
*/
static void
qla2x00_mem_free(struct qla_hw_data *ha)
qla2x00_free_fw_dump(struct qla_hw_data *ha)
{
if (ha->srb_mempool)
mempool_destroy(ha->srb_mempool);
if (ha->fce)
dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce,
ha->fce_dma);
......@@ -2852,6 +2886,29 @@ qla2x00_mem_free(struct qla_hw_data *ha)
ntohl(ha->fw_dump->eft_size), ha->eft, ha->eft_dma);
vfree(ha->fw_dump);
}
ha->fce = NULL;
ha->fce_dma = 0;
ha->eft = NULL;
ha->eft_dma = 0;
ha->fw_dump = NULL;
ha->fw_dumped = 0;
ha->fw_dump_reading = 0;
}
/*
* qla2x00_mem_free
* Frees all adapter allocated memory.
*
* Input:
* ha = adapter block pointer.
*/
static void
qla2x00_mem_free(struct qla_hw_data *ha)
{
qla2x00_free_fw_dump(ha);
if (ha->srb_mempool)
mempool_destroy(ha->srb_mempool);
if (ha->dcbx_tlv)
dma_free_coherent(&ha->pdev->dev, DCBX_TLV_DATA_SIZE,
......@@ -2925,8 +2982,6 @@ qla2x00_mem_free(struct qla_hw_data *ha)
ha->srb_mempool = NULL;
ha->ctx_mempool = NULL;
ha->eft = NULL;
ha->eft_dma = 0;
ha->sns_cmd = NULL;
ha->sns_cmd_dma = 0;
ha->ct_sns = NULL;
......@@ -2946,10 +3001,6 @@ qla2x00_mem_free(struct qla_hw_data *ha)
ha->gid_list = NULL;
ha->gid_list_dma = 0;
ha->fw_dump = NULL;
ha->fw_dumped = 0;
ha->fw_dump_reading = 0;
}
struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
......@@ -4049,6 +4100,7 @@ static struct pci_driver qla2xxx_pci_driver = {
.id_table = qla2xxx_pci_tbl,
.probe = qla2x00_probe_one,
.remove = qla2x00_remove_one,
.shutdown = qla2x00_shutdown,
.err_handler = &qla2xxx_err_handler,
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment