From: Arnd Bergmann <arnd@arndb.de>
To: linuxppc-dev@ozlabs.org
Subject: Re: [patch 6/7] xenon: add SMC support
Date: Wed, 7 Mar 2007 22:54:51 +0100 [thread overview]
Message-ID: <200703072254.51225.arnd@arndb.de> (raw)
In-Reply-To: <20070307180526.334384000@elitedvb.net>
On Wednesday 07 March 2007 19:01:50 Felix Domke wrote:
> It requires a userspace daemon.
Is that available somewhere? You should probably list a URL
for this in the driver and/or changelog
> +config XENON_SMC
> + bool "Xenon SMC"
> + depends on PPC_XENON
> + help
> + SMC controller in the Xbox 360.
> +
Please expand the acronym here. It's not a particularly unique
TLA after all.
> +struct xenon_smc
> +{
> + void __iomem *base;
> + unsigned long is_active;
> + wait_queue_head_t wait;
> +};
> +
> +static struct xenon_smc *first_smc;
Why do you think you need the global instance variable?
Normally, this should be pointed to by the pci device
private data.
> +#define to_smc(pdev) dev_get_drvdata(&pdev->dev)
> +
> +static int get_smc(struct xenon_smc *ctx, u8 *msg);
> +static void send_smc(struct xenon_smc *ctx, void *msg);
> +static irqreturn_t xenon_smc_irq(int irq, void *dev_id);
> +static ssize_t smc_write(struct file *file, const char __user *data,
> + size_t len, loff_t *ppos);
> +static int smc_ioctl(struct inode *inode, struct file *file,
> + unsigned int cmd, unsigned long arg);
> +static ssize_t smc_read(struct file *file, char __user *data,
> + size_t len, loff_t *ppos);
> +static int smc_open(struct inode *inode, struct file *file);
> +static int smc_release(struct inode *inode, struct file *file);
> +static int xenon_smc_init_one (struct pci_dev *pdev, const struct
> pci_device_id *ent); +static void __devexit xenon_smc_remove(struct pci_dev
> *pdev);
Don't do forward declarations of static functions, please instead
reorder them so you don't need these.
> +static struct miscdevice smc_miscdev = {
> + .minor = RTC_MINOR,
> + .name = "smc",
> + .fops = &smc_fops,
> +};
You can't grab the RTC device number if you don't support the
respective interfaces. Use a dynamic minor number instead!
> +static int get_smc(struct xenon_smc *ctx, u8 *msg)
> +{
> + if (readl(ctx->base + 0x94) & 4)
> + {
> + u32 *message = (u32*)msg;
> + int i;
> + writel(4, ctx->base + 0x94);
> + for (i=0; i<4; ++i)
> + message[i] = __raw_readl(ctx->base + 0x90);
> + writel(0, ctx->base + 0x94);
> + return 1;
> + }
> + return 0;
> +}
> +
> +static void send_smc(struct xenon_smc *ctx, void *msg)
> +{
> + while (!(readl(ctx->base + 0x84) & 4));
> + writel(4, ctx->base + 0x84);
> + __raw_writel(*(u32*)(msg+0), ctx->base + 0x80);
> + __raw_writel(*(u32*)(msg+4), ctx->base + 0x80);
> + __raw_writel(*(u32*)(msg+8), ctx->base + 0x80);
> + __raw_writel(*(u32*)(msg+12), ctx->base + 0x80);
> + writel(0, ctx->base + 0x84);
> +}
This needs to be cleaned up:
- don't use __raw_read/write on pci devices
- in the endless loop, use cpu_relax()
- avoid the casts if you can
> +static ssize_t smc_write(struct file *file, const char __user *data,
> + size_t len, loff_t *ppos)
> +{
> + unsigned char msg[16];
> + if (len != 16)
> + return -EINVAL;
> +
> + if (copy_from_user(msg, data, 16))
> + return -EFAULT;
> +
> + send_smc(first_smc, msg);
> +
> + return 16;
> +}
You can get the pointer to the smc from file->f_dentry->d_inode->i_private
if you put it in there
> +static int smc_ioctl(struct inode *inode, struct file *file,
> + unsigned int cmd, unsigned long arg)
> +{
> + return -ENODEV;
> +}
please kill this function, it's not needed.
> +static ssize_t smc_read(struct file *file, char __user *data,
> + size_t len, loff_t *ppos)
> +{
> + struct xenon_smc *ctx = first_smc;
> + int ret;
> + u8 msg[0x10];
> +
> + if (len != 16)
> + return -EINVAL;
> +
> + if (!(readl(ctx->base + 0x94) & 4))
> + {
> + if (file->f_flags & O_NONBLOCK)
> + return -EAGAIN;
> +
> + ret = wait_event_interruptible(ctx->wait, readl(ctx->base + 0x94) & 4);
> + if (ret < 0)
> + return ret;
> + }
> +
> + if (get_smc(ctx, msg) == 0)
> + return -EAGAIN;
> +
> + if (copy_to_user(data, msg, 0x10))
> + return -EFAULT;
> +
> + return 0x10;
> +}
> +
> +static int smc_open(struct inode *inode, struct file *file)
> +{
> + if (test_and_set_bit(0, &first_smc->is_active))
> + return -EBUSY;
> +
> + return nonseekable_open(inode, file);
> +}
This doesn't guarantee that you have only one fd to the device,
you can still get multiple copies through dup or fork.
> +
> + rc = misc_register(&smc_miscdev);
> + if (rc != 0)
> + {
You should be consistant with the indentation, opening braces here
and in other places (except function bodies) go at the end of the
previous line.
It's also more common to write 'if (!rc)' than comparing return values
against 0 or NULL.
Arnd <><
next prev parent reply other threads:[~2007-03-07 23:29 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-03-07 18:01 [patch 0/7] [RFC] Xenon support Felix Domke
2007-03-07 18:01 ` [patch 1/7] xenon: add PCI Vendor ID: Microsoft Felix Domke
2007-03-07 18:01 ` [patch 2/7] xenon: add platform support Felix Domke
2007-03-07 23:06 ` Arnd Bergmann
2007-03-07 18:01 ` [patch 3/7] xenon: udbg support (ugly) Felix Domke
2007-03-07 21:00 ` Geert Uytterhoeven
2007-03-07 18:01 ` [patch 4/7] xenon: add southbridge ethernet support Felix Domke
2007-03-07 23:27 ` Arnd Bergmann
2007-03-07 18:01 ` [patch 5/7] xenon: add SATA support Felix Domke
2007-03-07 21:02 ` Sergei Shtylyov
2007-03-07 21:07 ` Felix Domke
2007-03-07 21:14 ` Sergei Shtylyov
2007-03-07 18:01 ` [patch 6/7] xenon: add SMC support Felix Domke
2007-03-07 21:54 ` Arnd Bergmann [this message]
2007-03-08 23:29 ` Linas Vepstas
2007-03-07 18:01 ` [patch 7/7] xenon: add framebuffer support (ugly) Felix Domke
2007-03-07 21:06 ` [patch 0/7] [RFC] Xenon support Josh Boyer
2007-03-07 21:14 ` Felix Domke
2007-03-08 9:48 ` Benjamin Herrenschmidt
2007-03-08 0:35 ` Stephen Rothwell
2007-03-08 0:52 ` Felix Domke
2007-03-08 11:02 ` Christoph Hellwig
2007-03-08 23:50 ` Linas Vepstas
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=200703072254.51225.arnd@arndb.de \
--to=arnd@arndb.de \
--cc=linuxppc-dev@ozlabs.org \
/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;
as well as URLs for NNTP newsgroup(s).