[PATCH] crystalhd git.linuxtv.org kernel driver: FIX kernel freeze or OOPS in ISRs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



As expectable, the (unhandled?) false returns from the NULL pointer "fixes" may lead to kernel deadlock freezes and crashes in the ISRs.
Reproducing scenario: ctrl-c at capture startup, e.g.

Next try to fix it.

Future efforts should focus on the new kernel staging GPL driver.
--------------------------

Patch attached.

crystalhd git.linuxtv.org kernel driver: FIX kernel freeze or OOPS in ISRs

Signed-off-by: Thomas Schorpp <thomas.schorpp@xxxxxxxxx>

y
tom

diff --git a/driver/linux/crystalhd_cmds.c b/driver/linux/crystalhd_cmds.c
index cecd710..ba743df 100644
--- a/driver/linux/crystalhd_cmds.c
+++ b/driver/linux/crystalhd_cmds.c
@@ -32,6 +32,11 @@ static struct crystalhd_user *bc_cproc_get_uid(struct crystalhd_cmd *ctx)
 	struct crystalhd_user *user = NULL;
 	int i;
 
+	if (!ctx) {
+		dev_err(chddev(), "%s: Invalid Arg\n", __func__);
+		return user;
+	}
+
 	for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
 		if (!ctx->user[i].in_use) {
 			user = &ctx->user[i];
@@ -46,6 +51,11 @@ int bc_get_userhandle_count(struct crystalhd_cmd *ctx)
 {
 	int i, count = 0;
 
+	if (!ctx) {
+		dev_err(chddev(), "%s: Invalid Arg\n", __func__);
+		return BC_STS_INV_ARG;
+	}
+
 	for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
 		if (ctx->user[i].in_use)
 			count++;
@@ -154,7 +164,7 @@ static BC_STATUS bc_cproc_get_hwtype(struct crystalhd_cmd *ctx, crystalhd_ioctl_
 static BC_STATUS bc_cproc_reg_rd(struct crystalhd_cmd *ctx,
 				 crystalhd_ioctl_data *idata)
 {
-	if (!ctx || !idata)
+	if (!ctx || !ctx->hw_ctx || !idata)
 		return BC_STS_INV_ARG;
 	idata->udata.u.regAcc.Value = ctx->hw_ctx->pfnReadDevRegister(ctx->adp,
 					idata->udata.u.regAcc.Offset);
@@ -164,7 +174,7 @@ static BC_STATUS bc_cproc_reg_rd(struct crystalhd_cmd *ctx,
 static BC_STATUS bc_cproc_reg_wr(struct crystalhd_cmd *ctx,
 				 crystalhd_ioctl_data *idata)
 {
-	if (!ctx || !idata)
+	if (!ctx || !ctx->hw_ctx || !idata)
 		return BC_STS_INV_ARG;
 
 	ctx->hw_ctx->pfnWriteDevRegister(ctx->adp, idata->udata.u.regAcc.Offset,
@@ -176,7 +186,7 @@ static BC_STATUS bc_cproc_reg_wr(struct crystalhd_cmd *ctx,
 static BC_STATUS bc_cproc_link_reg_rd(struct crystalhd_cmd *ctx,
 				      crystalhd_ioctl_data *idata)
 {
-	if (!ctx || !idata)
+	if (!ctx || !ctx->hw_ctx || !idata)
 		return BC_STS_INV_ARG;
 
 	idata->udata.u.regAcc.Value = ctx->hw_ctx->pfnReadFPGARegister(ctx->adp,
@@ -187,7 +197,7 @@ static BC_STATUS bc_cproc_link_reg_rd(struct crystalhd_cmd *ctx,
 static BC_STATUS bc_cproc_link_reg_wr(struct crystalhd_cmd *ctx,
 				      crystalhd_ioctl_data *idata)
 {
-	if (!ctx || !idata)
+	if (!ctx || !ctx->hw_ctx || !idata)
 		return BC_STS_INV_ARG;
 
 	ctx->hw_ctx->pfnWriteFPGARegister(ctx->adp, idata->udata.u.regAcc.Offset,
@@ -201,7 +211,7 @@ static BC_STATUS bc_cproc_mem_rd(struct crystalhd_cmd *ctx,
 {
 	BC_STATUS sts = BC_STS_SUCCESS;
 
-	if (!ctx || !idata || !idata->add_cdata)
+	if (!ctx || !ctx->hw_ctx || !idata || !idata->add_cdata)
 		return BC_STS_INV_ARG;
 
 	if (idata->udata.u.devMem.NumDwords > (idata->add_cdata_sz / 4)) {
@@ -220,7 +230,7 @@ static BC_STATUS bc_cproc_mem_wr(struct crystalhd_cmd *ctx,
 {
 	BC_STATUS sts = BC_STS_SUCCESS;
 
-	if (!ctx || !idata || !idata->add_cdata)
+	if (!ctx || !ctx->hw_ctx || !idata || !idata->add_cdata)
 		return BC_STS_INV_ARG;
 
 	if (idata->udata.u.devMem.NumDwords > (idata->add_cdata_sz / 4)) {
@@ -307,7 +317,7 @@ static BC_STATUS bc_cproc_download_fw(struct crystalhd_cmd *ctx,
 
 	dev_dbg(chddev(), "Downloading FW\n");
 
-	if (!ctx || !idata || !idata->add_cdata || !idata->add_cdata_sz) {
+	if (!ctx || !ctx->hw_ctx || !idata || !idata->add_cdata || !idata->add_cdata_sz) {
 		dev_err(chddev(), "%s: Invalid Arg\n", __func__);
 		return BC_STS_INV_ARG;
 	}
@@ -350,7 +360,7 @@ static BC_STATUS bc_cproc_do_fw_cmd(struct crystalhd_cmd *ctx, crystalhd_ioctl_d
 	BC_STATUS sts;
 	uint32_t *cmd;
 
-	if (!(ctx->state & BC_LINK_INIT)) {
+	if ( !ctx || !idata || !(ctx->state & BC_LINK_INIT) || !ctx->hw_ctx) {
 		dev_dbg(dev, "Link invalid state do fw cmd %x \n", ctx->state);
 		return BC_STS_ERR_USAGE;
 	}
@@ -395,7 +405,7 @@ static void bc_proc_in_completion(struct crystalhd_dio_req *dio_hnd,
 		return;
 	}
 	if (sts == BC_STS_IO_USER_ABORT || sts == BC_STS_PWR_MGMT)
-		 return;
+		return;
 
 	dio_hnd->uinfo.comp_sts = sts;
 	dio_hnd->uinfo.ev_sts = 1;
@@ -407,6 +417,9 @@ static BC_STATUS bc_cproc_codein_sleep(struct crystalhd_cmd *ctx)
 	wait_queue_head_t sleep_ev;
 	int rc = 0;
 
+	if (!ctx)
+		return BC_STS_INV_ARG;
+
 	if (ctx->state & BC_LINK_SUSPEND)
 		return BC_STS_PWR_MGMT;
 
@@ -432,7 +445,7 @@ static BC_STATUS bc_cproc_hw_txdma(struct crystalhd_cmd *ctx,
 	wait_queue_head_t event;
 	int rc = 0;
 
-	if (!ctx || !idata || !dio) {
+	if (!ctx || !ctx->hw_ctx || !idata || !dio) {
 		dev_err(dev, "%s: Invalid Arg\n", __func__);
 		return BC_STS_INV_ARG;
 	}
@@ -573,7 +586,7 @@ static BC_STATUS bc_cproc_add_cap_buff(struct crystalhd_cmd *ctx,
 	struct crystalhd_dio_req *dio_hnd = NULL;
 	BC_STATUS sts = BC_STS_SUCCESS;
 
-	if (!ctx || !idata) {
+	if (!ctx || !ctx->hw_ctx || !idata) {
 		dev_err(dev, "%s: Invalid Arg\n", __func__);
 		return BC_STS_INV_ARG;
 	}
@@ -612,6 +625,11 @@ static BC_STATUS bc_cproc_fmt_change(struct crystalhd_cmd *ctx,
 {
 	BC_STATUS sts = BC_STS_SUCCESS;
 
+	if (!ctx || !dio) {
+		dev_err(chddev(), "%s: Invalid Arg\n", __func__);
+		return BC_STS_INV_ARG;
+	}
+
 	sts = crystalhd_hw_add_cap_buffer(ctx->hw_ctx, dio, 0);
 	if (sts != BC_STS_SUCCESS)
 		return sts;
@@ -673,6 +691,10 @@ static BC_STATUS bc_cproc_fetch_frame(struct crystalhd_cmd *ctx,
 static BC_STATUS bc_cproc_start_capture(struct crystalhd_cmd *ctx,
 					crystalhd_ioctl_data *idata)
 {
+	if (!ctx || !ctx->hw_ctx || !idata) {
+		return BC_STS_INV_ARG;
+	}
+
 	ctx->state |= BC_LINK_CAP_EN;
 
 	if( idata->udata.u.RxCap.PauseThsh )
@@ -705,7 +727,7 @@ static BC_STATUS bc_cproc_flush_cap_buffs(struct crystalhd_cmd *ctx,
 	struct device *dev = chddev();
 	struct crystalhd_rx_dma_pkt *rpkt;
 
-	if (!ctx || !idata) {
+	if (!ctx || !ctx->hw_ctx || !idata) {
 		dev_err(dev, "%s: Invalid Arg\n", __func__);
 		return BC_STS_INV_ARG;
 	}
@@ -745,8 +767,8 @@ static BC_STATUS bc_cproc_get_stats(struct crystalhd_cmd *ctx,
 	bool readTxOnly = false;
 	unsigned long irqflags;
 
-	if (!ctx || !idata) {
-		dev_err(chddev(), "%s: Invalid Arg\n", __func__);
+	if (!ctx || !ctx->hw_ctx || !idata) {
+		dev_err(chddev(), "%s: Invalid Arg ctx,hw,data: 0x%lx 0x%lx 0x%lx\n", __func__, (uintptr_t)(ctx->hw_ctx), (uintptr_t)ctx, (uintptr_t)idata);
 		return BC_STS_INV_ARG;
 	}
 
@@ -828,6 +850,10 @@ get_out:
 static BC_STATUS bc_cproc_reset_stats(struct crystalhd_cmd *ctx,
 				      crystalhd_ioctl_data *idata)
 {
+	if (!ctx || !ctx->hw_ctx || !idata) {
+		dev_err(chddev(), "%s: Invalid Arg\n", __func__);
+		return BC_STS_INV_ARG;
+	}
 	crystalhd_hw_stats(ctx->hw_ctx, NULL);
 
 	return BC_STS_SUCCESS;
@@ -948,9 +974,9 @@ BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *ida
 	BC_STATUS sts = BC_STS_SUCCESS;
 	struct crystalhd_rx_dma_pkt *rpkt = NULL;
 
-	if (!ctx || !idata) {
-		dev_err(dev, "Invalid Parameters\n");
-		return BC_STS_ERROR;
+	if (!ctx || !ctx->hw_ctx || !idata) {
+		dev_err(dev, "%s: Invalid Arg\n", __func__);
+		return BC_STS_INV_ARG;
 	}
 
 	if (ctx->state & BC_LINK_SUSPEND)
@@ -1017,6 +1043,11 @@ BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx)
 {
 	BC_STATUS sts = BC_STS_SUCCESS;
 
+	if (!ctx) {
+		dev_err(chddev(), "%s: Invalid Arg\n", __func__);
+		return BC_STS_INV_ARG;
+	}
+
 	sts = crystalhd_hw_resume(ctx->hw_ctx);
 	if (sts != BC_STS_SUCCESS)
 		return sts;
@@ -1049,13 +1080,13 @@ BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx,
 	struct crystalhd_user *uc;
 
 	if (!ctx || !user_ctx) {
-		dev_err(dev, "Invalid arg..\n");
+		dev_err(dev, "%s: Invalid Arg\n", __func__);
 		return BC_STS_INV_ARG;
 	}
 
 	uc = bc_cproc_get_uid(ctx);
 	if (!uc) {
-		dev_info(dev, "No free user context...\n");
+		dev_info(dev, "%s No free user context.\n", __func__);
 		return BC_STS_BUSY;
 	}
 
@@ -1093,19 +1124,21 @@ BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx,
  *
  * Called at the time of driver load.
  */
-BC_STATUS __devinit crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx,
+BC_STATUS crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx,
 				    struct crystalhd_adp *adp)
 {
-	struct device *dev = &adp->pdev->dev;
+	struct device *dev;
 	int i = 0;
 
-	if (!ctx || !adp) {
-		dev_err(dev, "%s: Invalid arg\n", __func__);
+	if (!ctx || !adp || !adp->pdev) {
+		printk(KERN_ERR "%s: Invalid arg.\n", __func__);
 		return BC_STS_INV_ARG;
 	}
 
+	dev = &adp->pdev->dev;
+
 	if (ctx->adp)
-		dev_dbg(dev, "Resetting Cmd context delete missing..\n");
+		dev_dbg(dev, "Resetting Cmd context delete missing.\n");
 
 	ctx->adp = adp;
 	for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
@@ -1114,15 +1147,19 @@ BC_STATUS __devinit crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx,
 		ctx->user[i].mode = DTS_MODE_INV;
 	}
 
-	ctx->hw_ctx = (struct crystalhd_hw*)kmalloc(sizeof(struct crystalhd_hw), GFP_KERNEL);
-
-	memset(ctx->hw_ctx, 0, sizeof(struct crystalhd_hw));
+	if(ctx->hw_ctx == NULL) {
+		ctx->hw_ctx = (struct crystalhd_hw*)kmalloc(sizeof(struct crystalhd_hw), GFP_KERNEL);
+		if(ctx->hw_ctx != NULL)
+			memset(ctx->hw_ctx, 0, sizeof(struct crystalhd_hw));
+		else
+			return BC_STS_ERROR;
 
-	/*Open and Close the Hardware to put it in to sleep state*/
-	crystalhd_hw_open(ctx->hw_ctx, ctx->adp);
-	crystalhd_hw_close(ctx->hw_ctx, ctx->adp);
-	kfree(ctx->hw_ctx);
-	ctx->hw_ctx = NULL;
+		/*Open and Close the Hardware to put it in to sleep state*/
+		crystalhd_hw_open(ctx->hw_ctx, ctx->adp);
+		crystalhd_hw_close(ctx->hw_ctx, ctx->adp);
+		kfree(ctx->hw_ctx);
+		ctx->hw_ctx = NULL;
+	}
 
 	return BC_STS_SUCCESS;
 }
@@ -1136,10 +1173,15 @@ BC_STATUS __devinit crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx,
  *
  * Called at the time of driver un-load.
  */
-BC_STATUS __devexit crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx)
+BC_STATUS crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx)
 {
 	dev_dbg(chddev(), "Deleting Command context..\n");
 
+	if (!ctx) {
+		dev_err(chddev(), "%s: Invalid arg\n", __func__);
+		return BC_STS_INV_ARG;
+	}
+
 	ctx->adp = NULL;
 
 	return BC_STS_SUCCESS;
@@ -1165,8 +1207,8 @@ crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx, uint32_t cm
 	crystalhd_cmd_proc cproc = NULL;
 	unsigned int i, tbl_sz;
 
-	if (!ctx) {
-		dev_err(dev, "Invalid arg.. Cmd[%d]\n", cmd);
+	if (!ctx || !uc) {
+		dev_err(dev, "Invalid arg. Cmd[%d]\n", cmd);
 		return NULL;
 	}
 
diff --git a/driver/linux/crystalhd_fleafuncs.c b/driver/linux/crystalhd_fleafuncs.c
index 1aa7115..f76d122 100644
--- a/driver/linux/crystalhd_fleafuncs.c
+++ b/driver/linux/crystalhd_fleafuncs.c
@@ -1344,7 +1344,9 @@ BCHP_SCRUB_CTRL_BI_CMAC_127_96		0x000f6018			CMAC Bits[127:96]
 bool crystalhd_flea_start_device(struct crystalhd_hw *hw)
 {
 	uint32_t	regVal	= 0;
-	bool		bRetVal = false;
+
+	if (!hw)
+		return false;
 
 	/*
 	-- Issue Core reset to bring in the default values in place
@@ -1430,7 +1432,7 @@ bool crystalhd_flea_start_device(struct crystalhd_hw *hw)
 
 	msleep_interruptible(1);
 
-	return bRetVal;
+	return true;
 }
 
 
diff --git a/driver/linux/crystalhd_hw.c b/driver/linux/crystalhd_hw.c
index cf8fefb..bffb468 100644
--- a/driver/linux/crystalhd_hw.c
+++ b/driver/linux/crystalhd_hw.c
@@ -38,7 +38,7 @@
 BC_STATUS crystalhd_hw_open(struct crystalhd_hw *hw, struct crystalhd_adp *adp)
 {
 	struct device *dev;
-	if (!hw || !adp) {
+	if (!hw || !adp || !adp->pdev) {
 		printk(KERN_ERR "%s: Invalid Arguments\n", __func__);
 		return BC_STS_INV_ARG;
 	}
@@ -110,7 +110,10 @@ BC_STATUS crystalhd_hw_open(struct crystalhd_hw *hw, struct crystalhd_adp *adp)
 	hw->rx_pkt_tag_seed = 0x70029070;
 
 	hw->stop_pending = 0;
-	hw->pfnStartDevice(hw);
+	if (!hw->pfnStartDevice(hw)) {
+		printk(KERN_ERR "%s: Failed to Start Device! \n", __func__);
+		return BC_STS_ERROR;
+	}
 	hw->dev_started = true;
 
 	dev_dbg(dev, "Opening HW. hw:0x%lx, hw->adp:0x%lx\n",
@@ -121,9 +124,9 @@ BC_STATUS crystalhd_hw_open(struct crystalhd_hw *hw, struct crystalhd_adp *adp)
 
 BC_STATUS crystalhd_hw_close(struct crystalhd_hw *hw, struct crystalhd_adp *adp)
 {
-	if (!hw) {
+	if (!hw || !adp) {
 		printk(KERN_ERR "%s: Invalid Arguments\n", __func__);
-		return BC_STS_SUCCESS;
+		return BC_STS_INV_ARG;
 	}
 
 	if (!hw->dev_started)
@@ -390,12 +393,12 @@ BC_STATUS crystalhd_hw_tx_req_complete(struct crystalhd_hw *hw,
 	struct tx_dma_pkt *tx_req;
 
 	if (!hw || !list_id) {
-		printk(KERN_ERR "%s: Invalid Arg!!\n", __func__);
+		printk(KERN_ERR "%s: Invalid Arg\n", __func__);
 		return BC_STS_INV_ARG;
 	}
 
 	tx_req = (struct tx_dma_pkt *)crystalhd_dioq_find_and_fetch(hw->tx_actq, list_id);
-	if (!tx_req) {
+	if (!tx_req || !tx_req->dio_req || !tx_req->cb_event) {
 		if (cs != BC_STS_IO_USER_ABORT)
 			dev_err(&hw->adp->pdev->dev, "Find/Fetch: no req!\n");
 		return BC_STS_NO_DATA;
@@ -1047,8 +1050,8 @@ BC_STATUS crystalhd_hw_resume(struct crystalhd_hw *hw)
 	hw->rx_list_post_index = 0;
 	hw->tx_list_post_index = 0;
 
-	if (hw->pfnStartDevice(hw)) {
-		dev_info(&hw->adp->pdev->dev, "Failed to Start Device!!\n");
+	if (!hw->pfnStartDevice(hw)) {
+		dev_info(&hw->adp->pdev->dev, "Failed to resume start device!\n");
 		return BC_STS_ERROR;
 	}
 
diff --git a/driver/linux/crystalhd_linkfuncs.c b/driver/linux/crystalhd_linkfuncs.c
index 8366cc3..c8be3ab 100644
--- a/driver/linux/crystalhd_linkfuncs.c
+++ b/driver/linux/crystalhd_linkfuncs.c
@@ -469,8 +469,8 @@ bool crystalhd_link_start_device(struct crystalhd_hw *hw)
 	uint32_t dbg_options, glb_cntrl = 0, reg_pwrmgmt = 0;
 	struct device *dev;
 
-	if (!hw)
-		return -EINVAL;
+	if (!hw || !hw->adp || !hw->adp->pdev)
+		return false;
 
 	dev = &hw->adp->pdev->dev;
 
@@ -957,6 +957,9 @@ void crystalhd_link_tx_isr(struct crystalhd_hw *hw, uint32_t int_sts)
 {
 	uint32_t err_sts;
 
+	if (!hw)
+		return;
+
 	if (int_sts & INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_MASK)
 		crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 0,
 					   BC_STS_SUCCESS);
@@ -1995,22 +1998,15 @@ bool crystalhd_link_hw_interrupt_handle(struct crystalhd_adp *adp, struct crysta
 {
 	uint32_t intr_sts = 0;
 	uint32_t deco_intr = 0;
-	bool rc = false;
 
-	if (!adp || !hw->dev_started)
-		return rc;
+	if (!adp || !hw || !hw->dev_started)
+		return false;
 
 	hw->stats.num_interrupts++;
 
 	deco_intr = hw->pfnReadDevRegister(hw->adp, Stream2Host_Intr_Sts);
 	intr_sts  = hw->pfnReadFPGARegister(hw->adp, INTR_INTR_STATUS);
 
-	if (intr_sts) {
-		/* let system know we processed interrupt..*/
-		rc = true;
-		hw->stats.dev_interrupts++;
-	}
-
 	if (deco_intr && (deco_intr != 0xdeaddead)) {
 
 		if (deco_intr & 0x80000000) {
@@ -2026,7 +2022,6 @@ bool crystalhd_link_hw_interrupt_handle(struct crystalhd_adp *adp, struct crysta
 
 		hw->pfnWriteDevRegister(hw->adp, Stream2Host_Intr_Sts, deco_intr);
 		hw->pfnWriteDevRegister(hw->adp, Stream2Host_Intr_Sts, 0);
-		rc = 1;
 	}
 
 	/* Rx interrupts */
@@ -2036,14 +2031,17 @@ bool crystalhd_link_hw_interrupt_handle(struct crystalhd_adp *adp, struct crysta
 	crystalhd_link_tx_isr(hw, intr_sts);
 
 	/* Clear interrupts */
-	if (rc) {
-		if (intr_sts)
-			hw->pfnWriteFPGARegister(hw->adp, INTR_INTR_CLR_REG, intr_sts);
+	if (intr_sts)
+		hw->pfnWriteFPGARegister(hw->adp, INTR_INTR_CLR_REG, intr_sts);
 
-		hw->pfnWriteFPGARegister(hw->adp, INTR_EOI_CTRL, 1);
+	hw->pfnWriteFPGARegister(hw->adp, INTR_EOI_CTRL, 1);
+
+	if (intr_sts) {
+		/* Let system know we have processed interrupts, and rc ret is always true unless invalid args. */
+		hw->stats.dev_interrupts++;
 	}
 
-	return rc;
+	return true;
 }
 
 /* Dummy private function */
diff --git a/driver/linux/crystalhd_lnx.c b/driver/linux/crystalhd_lnx.c
index 64e66ad..8608aea 100644
--- a/driver/linux/crystalhd_lnx.c
+++ b/driver/linux/crystalhd_lnx.c
@@ -431,7 +431,7 @@ static const struct file_operations chd_dec_fops = {
 	.llseek		= noop_llseek,
 };
 
-static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp)
+static int chd_dec_init_chdev(struct crystalhd_adp *adp)
 {
 	struct device *xdev = &adp->pdev->dev;
 	struct device *dev;
@@ -498,7 +498,7 @@ fail:
 	return rc;
 }
 
-static void __devexit chd_dec_release_chdev(struct crystalhd_adp *adp)
+static void chd_dec_release_chdev(struct crystalhd_adp *adp)
 {
 	crystalhd_ioctl_data *temp = NULL;
 	if (!adp)
@@ -523,7 +523,7 @@ static void __devexit chd_dec_release_chdev(struct crystalhd_adp *adp)
 	/*crystalhd_delete_elem_pool(adp); */
 }
 
-static int __devinit chd_pci_reserve_mem(struct crystalhd_adp *pinfo)
+static int chd_pci_reserve_mem(struct crystalhd_adp *pinfo)
 {
 	struct device *dev = &pinfo->pdev->dev;
 	int rc;
@@ -582,7 +582,7 @@ static int __devinit chd_pci_reserve_mem(struct crystalhd_adp *pinfo)
 	return 0;
 }
 
-static void __devexit chd_pci_release_mem(struct crystalhd_adp *pinfo)
+static void chd_pci_release_mem(struct crystalhd_adp *pinfo)
 {
 	if (!pinfo)
 		return;
@@ -597,7 +597,7 @@ static void __devexit chd_pci_release_mem(struct crystalhd_adp *pinfo)
 }
 
 
-static void __devexit chd_dec_pci_remove(struct pci_dev *pdev)
+static void chd_dec_pci_remove(struct pci_dev *pdev)
 {
 	struct crystalhd_adp *pinfo;
 	BC_STATUS sts = BC_STS_SUCCESS;
@@ -625,7 +625,7 @@ static void __devexit chd_dec_pci_remove(struct pci_dev *pdev)
 	g_adp_info = NULL;
 }
 
-static int __devinit chd_dec_pci_probe(struct pci_dev *pdev,
+static int chd_dec_pci_probe(struct pci_dev *pdev,
 			     const struct pci_device_id *entry)
 {
 	struct device *dev = &pdev->dev;
@@ -815,7 +815,7 @@ MODULE_DEVICE_TABLE(pci, chd_dec_pci_id_table);
 static struct pci_driver bc_chd_driver = {
 	.name     = "crystalhd",
 	.probe    = chd_dec_pci_probe,
-	.remove   = __devexit_p(chd_dec_pci_remove),
+	.remove   = chd_dec_pci_remove,
 	.id_table = chd_dec_pci_id_table,
 	.suspend  = chd_dec_pci_suspend,
 	.resume   = chd_dec_pci_resume
diff --git a/driver/linux/crystalhd_misc.c b/driver/linux/crystalhd_misc.c
index 410ab9d..56fbb51 100644
--- a/driver/linux/crystalhd_misc.c
+++ b/driver/linux/crystalhd_misc.c
@@ -512,8 +512,8 @@ void *crystalhd_dioq_fetch_wait(struct crystalhd_hw *hw, uint32_t to_secs, uint3
 			if(down_interruptible(&hw->fetch_sem))
 				goto sem_error;
 			r_pkt = crystalhd_dioq_fetch(ioq);
-			/* If format change packet, then return with out checking anything */
-			if (r_pkt->flags & (COMP_FLAG_PIB_VALID | COMP_FLAG_FMT_CHANGE))
+			/* If format change packet then return without checking anything */
+			if (!r_pkt || r_pkt->flags & (COMP_FLAG_PIB_VALID | COMP_FLAG_FMT_CHANGE))
 				goto sem_rel_return;
 			if (hw->adp->pdev->device == BC_PCI_DEVID_LINK) {
 				picYcomp = link_GetRptDropParam(hw, hw->PICHeight, hw->PICWidth, (void *)r_pkt);

[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux