From: Alan Cox <alan@lxorguk.ukuu.org.uk>
To: pavan_savoy@ti.com
Cc: marcel@holtmann.org, gregkh@suse.de,
linux-kernel@vger.kernel.org, pavan_savoy@yahoo.co.in
Subject: Re: [PATCH] drivers:staging: sources for ST core
Date: Tue, 30 Mar 2010 12:22:01 +0100 [thread overview]
Message-ID: <20100330122201.02accf0f@lxorguk.ukuu.org.uk> (raw)
In-Reply-To: <1269559223-4043-3-git-send-email-pavan_savoy@ti.com>
> +/* all debug macros go in here */
> +#define ST_DRV_ERR(fmt, arg...) printk(KERN_ERR "(stc):"fmt"\n" , ## arg)
> +#if defined(DEBUG) /* limited debug messages */
> +#define ST_DRV_DBG(fmt, arg...) printk(KERN_INFO "(stc):"fmt"\n" , ## arg)
> +#define ST_DRV_VER(fmt, arg...)
> +#elif defined(VERBOSE) /* very verbose */
> +#define ST_DRV_DBG(fmt, arg...) printk(KERN_INFO "(stc):"fmt"\n" , ## arg)
> +#define ST_DRV_VER(fmt, arg...) printk(KERN_INFO "(stc):"fmt"\n" , ## arg)
> +#else /* error msgs only */
> +#define ST_DRV_DBG(fmt, arg...)
> +#define ST_DRV_VER(fmt, arg...)
> +#endif
As Greg said earlier - needs to be using the standard debug macros
> +/*
> + * local data instances
> + */
> +static struct st_data_s *st_gdata;
> +/* function pointer pointing to either,
> + * st_kim_recv during registration to receive fw download responses
> + * st_int_recv after registration to receive proto stack responses
> + */
> +void (*st_recv) (const unsigned char *data, long count);
Need some form of context so you can have multiple device instances and
avoid games with globals (which always end up in pain)
> +
> +/********************************************************************/
> +/* internal misc functions */
> +bool is_protocol_list_empty(void)
> +{
> + unsigned char i = 0;
> + ST_DRV_DBG(" %s ", __func__);
> + for (i = 0; i < ST_MAX; i++) {
> + if (st_gdata->list[i] != NULL)
> + return ST_NOTEMPTY;
> + /* not empty */
> + }
> + /* list empty */
> + return ST_EMPTY;
Why not just keep a count of entries you've added/removed ?
> + * This is the internal write function - a wrapper
> + * to tty->ops->write
> + */
> +int st_int_write(const unsigned char *data, int count)
> +{
> +#ifdef VERBOSE /* for debug */
> + int i;
> +#endif
> + struct tty_struct *tty;
> + if (unlikely(st_gdata == NULL || st_gdata->tty == NULL)) {
> + ST_DRV_ERR("tty unavailable to perform write");
You need to use the tty pointer passed, you don't want to walk
tty->something and back because you may race a hangup. Plus you would
need to manage the krefs (object references)
> + return ST_ERR_FAILURE;
Should be using Linux error codes for upstream. A global search/replace
of the ST_ERR_xxx for a similar -Efoo code will do the trick I think
> +/*
> + * push the skb received to relevant
> + * protocol stacks
> + */
> +void st_send_frame(enum proto_type protoid, struct sk_buff *skb)
> +{
> + ST_DRV_DBG(" %s(prot:%d) ", __func__, protoid);
> +
> + if (unlikely
> + (st_gdata == NULL || skb == NULL
> + || st_gdata->list[protoid] == NULL)) {
> + ST_DRV_ERR("protocol %d not registered, no data to send?",
> + protoid);
> + kfree_skb(skb);
> + return;
> + }
What is the locking rule to ensure I don't unregister a protocol as send
frame is called ?
> + * to call registration complete callbacks
> + * of all protocol stack drivers
> + */
> +void st_reg_complete(char err)
> +{
> + unsigned char i = 0;
> + ST_DRV_DBG(" %s ", __func__);
> + for (i = 0; i < ST_MAX; i++) {
> + if (likely(st_gdata != NULL && st_gdata->list[i] != NULL &&
Except on very hot paths that go odd ways likely and unlikely are
normally a loss.
> +static inline int st_check_data_len(int protoid, int len)
> +{
> + register int room = skb_tailroom(st_gdata->rx_skb);
No need to use register - gcc is generally smarter than humans here,
especially in the long term. You may optimise perfectly for a single
cpu/compiler revision but not for all
> +/* Decodes received RAW data and forwards to corresponding
> + * client drivers (Bluetooth,FM,GPS..etc).
> + *
> + */
> +void st_int_recv(const unsigned char *data, long count)
There are lots of globals here, in part it seems due to the lack of any
kind of context being passed around
>
> + /* this function can be invoked in more then one context.
> + * so have a lock */
It's a good idea to document what data is locked and what the data
locking assumptions are. I'm finding that part of the code quite hard to
follow
> +/*
> + * internal wakeup function
> + * called from either
> + * - TTY layer when write's finished
> + * - st_write (in context of the protocol stack)
> + */
> +void st_tx_wakeup(struct st_data_s *st_data)
> + while ((skb = st_int_dequeue(st_data))) {
Called in two paths but st_int_dequeue seems to have no internal locking
> +/* functions called from ST KIM
> +*/
> +void kim_st_list_protocols(char *buf)
> +{
> + unsigned long flags = 0;
> +#ifdef DEBUG
> + unsigned char i = ST_MAX;
> +#endif
> + spin_lock_irqsave(&st_gdata->lock, flags);
> +#ifdef DEBUG /* more detailed log */
> + for (i = 0; i < ST_MAX; i++) {
> + if (i == 0) {
> + sprintf(buf, "%s is %s", protocol_strngs[i],
> + st_gdata->list[i] !=
> + NULL ? "Registered" : "Unregistered");
Always a good idea to use snprintf and track size (plus pass buffer size)
it avoida accidents later. Or also see the seq_ interface when you want
to build proc type files.
> +/********************************************************************/
> +/*
> + * functions called from protocol stack drivers
> + * to be EXPORT-ed
> + */
> +long st_register(struct st_proto_s *new_proto)
> +{
> + long err = ST_SUCCESS;
>
> + * functions called from TTY layer
> + */
> +static int st_tty_open(struct tty_struct *tty)
> +{
> + int err = ST_SUCCESS;
> + ST_DRV_DBG("%s ", __func__);
> +
> + st_gdata->tty = tty;
If you do this you need to use krefs and manage the reference properly
over open/close/hangup
> +static void st_tty_close(struct tty_struct *tty)
> +{
> + /* Flush any pending characters in the driver and discipline. */
> + tty_driver_flush_buffer(tty);
Close will deal with this anyway
> +static void st_tty_receive(struct tty_struct *tty, const unsigned char *data,
> + char *tty_flags, int count)
> +{
> +#ifdef VERBOSE
> + long i;
> + printk(KERN_ERR "incoming data...\n");
> + for (i = 0; i < count; i++)
> + printk(" %x", data[i]);
> + printk(KERN_ERR "\n.. data end\n");
> +#endif
> +
> + /*
> + * if fw download is in progress then route incoming data
> + * to KIM for validation
> + */
> + st_recv(data, count);
If you passed tty up and used tty->disc_data you'd be able to handle
multiple devices
> +/********************************************************************/
> +static int __init st_core_init(void)
> +{
> + long err;
> + static struct tty_ldisc_ops *st_ldisc_ops;
> +
> + /* populate and register to TTY line discipline */
> + st_ldisc_ops = kzalloc(sizeof(*st_ldisc_ops), GFP_KERNEL);
> + if (!st_ldisc_ops) {
> + ST_DRV_ERR("no mem to allocate");
> + return -ENOMEM;
> + }
> +
> + st_ldisc_ops->magic = TTY_LDISC_MAGIC;
> + st_ldisc_ops->name = "n_st"; /*"n_hci"; */
> + st_ldisc_ops->open = st_tty_open;
> + st_ldisc_ops->close = st_tty_close;
> + st_ldisc_ops->receive_buf = st_tty_receive;
> + st_ldisc_ops->write_wakeup = st_tty_wakeup;
> + st_ldisc_ops->flush_buffer = st_tty_flush_buffer;
> + st_ldisc_ops->owner = THIS_MODULE;
You could just declare this as a static struct like other drivers do ?
next prev parent reply other threads:[~2010-03-30 11:18 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-03-25 23:20 [v4] New ldisc for WiLink7.0 pavan_savoy
2010-03-25 23:20 ` [PATCH] serial: TTY: new ldiscs for staging pavan_savoy
2010-03-25 23:20 ` [PATCH] drivers:staging: sources for ST core pavan_savoy
2010-03-25 23:20 ` [PATCH] drivers:staging: sources for Init manager module pavan_savoy
2010-03-25 23:20 ` [PATCH] drivers:staging: sources for HCI LL PM protocol pavan_savoy
2010-03-25 23:20 ` [PATCH] drivers:staging: sources for ST header file pavan_savoy
2010-03-25 23:20 ` [PATCH] drivers:staging: Kconfig, Makefile for TI's ST ldisc pavan_savoy
2010-03-25 23:20 ` [PATCH] Documentation:staging: add TODO and ABI to ti-st pavan_savoy
2010-03-25 23:20 ` [PATCH] bluetooth: BT driver using ST for TI combo devices pavan_savoy
2010-03-30 11:24 ` [PATCH] drivers:staging: sources for HCI LL PM protocol Alan Cox
2010-03-30 15:03 ` Pavan Savoy
2010-03-30 18:33 ` Alan Cox
2010-03-30 11:22 ` Alan Cox [this message]
2010-03-30 15:53 ` [PATCH] drivers:staging: sources for ST core Pavan Savoy
2010-03-30 20:38 ` Greg KH
2010-03-30 21:05 ` Pavan Savoy
2010-03-30 21:47 ` Greg KH
2010-03-31 2:24 ` Joe Perches
2010-03-25 23:30 ` [PATCH] serial: TTY: new ldiscs for staging Alan Cox
2010-03-26 15:08 ` Pavan Savoy
2010-03-28 4:58 ` [v4] New ldisc for WiLink7.0 Greg KH
2010-03-30 22:50 [PATCH] drivers:staging: sources for ST core Pavan Savoy
2010-03-31 17:30 ` Greg KH
2010-03-31 18:02 ` Pavan Savoy
2010-03-31 18:19 ` Greg KH
2010-03-31 19:27 Pavan Savoy
2010-03-31 20:24 ` Greg KH
2010-03-31 23:57 ` Pavan Savoy
2010-04-01 9:20 ` Alan Cox
2010-04-01 17:20 Pavan Savoy
2010-04-01 22:43 ` Pavan Savoy
2010-04-01 23:27 ` Alan Cox
2010-04-05 16:18 ` Pavan Savoy
2010-04-08 18:16 New ldisc for WiLink7.0 pavan_savoy
2010-04-08 18:16 ` [PATCH] serial: TTY: new ldiscs for staging pavan_savoy
2010-04-08 18:16 ` [PATCH] drivers:staging: sources for ST core pavan_savoy
2010-04-13 15:06 ` Pavan Savoy
2010-04-13 15:12 ` Alan Cox
2010-04-19 18:37 ` Pavan Savoy
2010-04-26 21:24 ` Pavan Savoy
2010-04-26 22:03 ` Alan Cox
2010-04-26 22:06 ` Pavan Savoy
2010-04-27 16:15 Pavan Savoy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100330122201.02accf0f@lxorguk.ukuu.org.uk \
--to=alan@lxorguk.ukuu.org.uk \
--cc=gregkh@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=marcel@holtmann.org \
--cc=pavan_savoy@ti.com \
--cc=pavan_savoy@yahoo.co.in \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®