summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorShobek Sam Attupurath <sattupurath@nvidia.com>2013-10-24 14:07:03 +0530
committerHarry Hong <hhong@nvidia.com>2013-10-31 03:48:08 -0700
commitdb4316cda1b5d073da4572feb76524a155d44124 (patch)
tree5362732e4a6a5d9a45e325223249efc1a976277e /drivers
parent23af567e569a6f0259b9ad848671201555042c07 (diff)
misc: ti-st: Create rx_list before all channels are registered
rx_list should be created before the channels are registered else when the chip sends data after registering channel 4 we may encounter a crash. Bug 1390113 Change-Id: Ieb1e0bbeda7845a156ee6636f233c79df36ba7db Signed-off-by: Shobek Sam Attupurath <sattupurath@nvidia.com> Reviewed-on: http://git-master/r/303251 Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Tested-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/misc/ti-st/tty_hci.c51
1 files changed, 30 insertions, 21 deletions
diff --git a/drivers/misc/ti-st/tty_hci.c b/drivers/misc/ti-st/tty_hci.c
index 591b0be944ca..ab98515da3a2 100644
--- a/drivers/misc/ti-st/tty_hci.c
+++ b/drivers/misc/ti-st/tty_hci.c
@@ -142,8 +142,14 @@ int hci_tty_open(struct inode *inod, struct file *file)
pr_info("inside %s (%p, %p)\n", __func__, inod, file);
hst = kzalloc(sizeof(*hst), GFP_KERNEL);
+
+ if (!hst)
+ return -ENOMEM;
+
file->private_data = hst;
- hst = file->private_data;
+
+ skb_queue_head_init(&hst->rx_list);
+ init_waitqueue_head(&hst->data_q);
for (i = 0; i < MAX_BT_CHNL_IDS; i++) {
ti_st_proto[i].priv_data = hst;
@@ -161,12 +167,23 @@ int hci_tty_open(struct inode *inod, struct file *file)
hst->reg_status = -EINPROGRESS;
err = st_register(&ti_st_proto[i]);
- if (!err)
- goto done;
+
+ if (!err) {
+ hst->st_write = ti_st_proto[i].write;
+ if (!hst->st_write) {
+ pr_err("undefined ST write function");
+ err = -EIO;
+ goto error;
+ }
+ continue;
+ }
if (err != -EINPROGRESS) {
pr_err("st_register failed %d", err);
- return err;
+ /* this channel is not registered - don't unregister */
+ --i;
+ /*return err;*/
+ goto error;
}
/* ST is busy with either protocol
@@ -192,26 +209,18 @@ int hci_tty_open(struct inode *inod, struct file *file)
return -EAGAIN;
}
-done:
- hst->st_write = ti_st_proto[i].write;
- if (!hst->st_write) {
- pr_err("undefined ST write function");
- for (i = 0; i < MAX_BT_CHNL_IDS; i++) {
- /* Undo registration with ST */
- err = st_unregister(&ti_st_proto[i]);
- if (err)
- pr_err("st_unregister() failed with "
- "error %d", err);
- hst->st_write = NULL;
- }
- return -EIO;
- }
}
- skb_queue_head_init(&hst->rx_list);
- init_waitqueue_head(&hst->data_q);
-
return 0;
+
+error:
+ while (i-- >= 0)
+ if (st_unregister(&ti_st_proto[i]))
+ pr_err("st_unregister() failed with ");
+
+ kfree(hst);
+
+ return err;
}
/** hci_tty_release Function