From: Andrew Morton <akpm@linux-foundation.org>
To: Michael Buesch <mb@bu3sch.de>
Cc: "linux-kernel" <linux-kernel@vger.kernel.org>,
bcm43xx-dev@lists.berlios.de, netdev@vger.kernel.org,
linux-wireless@vger.kernel.org,
Gary Zambrano <zambrano@broadcom.com>
Subject: Re: [PATCH] Merge the Sonics Silicon Backplane subsystem
Date: Fri, 27 Jul 2007 12:03:18 -0700 [thread overview]
Message-ID: <20070727120318.54d18cfc.akpm@linux-foundation.org> (raw)
In-Reply-To: <200707271857.24162.mb@bu3sch.de>
On Fri, 27 Jul 2007 18:57:20 +0200
Michael Buesch <mb@bu3sch.de> wrote:
> The Sonics Silicon Backplane is a mini-bus used on
> various Broadcom chips and embedded devices.
> Devices using the SSB include b44, bcm43xx and various
> Broadcom based wireless routers.
> A b44 and bcm43xx port and a SSB based OHCI driver is available.
>
hm, slim pickings for me here. Nice looking code.
checkpatch finds a few coding style glitches. Lots of 80-col violations
which you might choose ignore (comments on #defines in headers are
especially hard) but these guys:
ERROR: "foo * bar" should be "foo *bar"
#4156: FILE: drivers/ssb/ssb_private.h:119:
+extern struct ssb_bus * ssb_pci_dev_to_bus(struct pci_dev *pdev);
are worth addressing.
> ...
>
> --- /dev/null
> +++ b/drivers/ssb/driver_pcicore.c
> @@ -0,0 +1,564 @@
>
> ...
>
> +u32 pci_iobase = 0x100;
> +u32 pci_membase = SSB_PCI_DMA;
These are quite poor names for global symbols.
> +static struct resource ssb_pcicore_mem_resource = {
> + .name = "SSB PCIcore external memory",
> + .start = SSB_PCI_DMA,
> + .end = (u32)SSB_PCI_DMA + (u32)SSB_PCI_DMA_SZ - 1,
> + .flags = IORESOURCE_MEM,
> +};
start and end here are resource_size_t. Forcing them to u32 seems
inappropriate.
> +void ssb_pcicore_init(struct ssb_pcicore *pc)
Please check that all newly-added global symbols do indeed need global scope.
> +static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
> + u8 address, u16 data)
> +{
> + const u16 mdio_control = 0x128;
> + const u16 mdio_data = 0x12C;
> + u32 v;
> + int i;
> +
> + v = 0x80; /* Enable Preamble Sequence */
> + v |= 0x2; /* MDIO Clock Divisor */
> + pcicore_write32(pc, mdio_control, v);
> +
> + v = (1 << 30); /* Start of Transaction */
> + v |= (1 << 28); /* Write Transaction */
> + v |= (1 << 17); /* Turnaround */
> + v |= (u32)device << 22;
> + v |= (u32)address << 18;
> + v |= data;
> + pcicore_write32(pc, mdio_data, v);
> + udelay(10);
mystery udelays are usually worth a comment.
> + for (i = 0; i < 10; i++) {
> + v = pcicore_read32(pc, mdio_control);
> + if (v & 0x100 /* Trans complete */)
> + break;
> + msleep(1);
> + }
> + pcicore_write32(pc, mdio_control, 0);
> +}
>
> ...
>
> +
> +static void ssb_buses_lock(void)
> +{
> + if (!ssb_is_early_boot)
> + mutex_lock(&buses_mutex);
> +}
> +
> +static void ssb_buses_unlock(void)
> +{
> + if (!ssb_is_early_boot)
> + mutex_unlock(&buses_mutex);
> +}
Some comments are neeeded here to explain why we're jumping through this
hoop. It's normally OK to take a mutex early in boot, so one wonders
what's happening.
> +EXPORT_SYMBOL(ssb_clockspeed);
Please check that all newly-added exports really need to be exported (I'm
sure they do, but..)
> +static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask,
> + int timeout, int set)
> +{
> + int i;
> + u32 val;
> +
> + for (i = 0; i < timeout; i++) {
> + val = ssb_read32(dev, reg);
> + if (set) {
> + if (val & bitmask)
> + return 0;
> + } else {
> + if (!(val & bitmask))
> + return 0;
> + }
> + udelay(10);
> + }
> + printk(KERN_ERR PFX "Timeout waiting for bitmask %08X on "
> + "register %04X to %s.\n",
> + bitmask, reg, (set ? "set" : "clear"));
> +
> + return -ETIMEDOUT;
> +}
So `timeout' is in units of ten-microseconds. Unusual.
> +void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags)
> +{
> + u32 reject;
> +
> + if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_RESET)
> + return;
> +
> + reject = ssb_tmslow_reject_bitmask(dev);
> + ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK);
> + ssb_wait_bit(dev, SSB_TMSLOW, reject, 1000, 1);
> + ssb_wait_bit(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0);
> + ssb_write32(dev, SSB_TMSLOW,
> + SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
> + reject | SSB_TMSLOW_RESET |
> + core_specific_flags);
> + /* flush */
> + ssb_read32(dev, SSB_TMSLOW);
> + udelay(1);
> +
> + ssb_write32(dev, SSB_TMSLOW,
> + reject | SSB_TMSLOW_RESET |
> + core_specific_flags);
> + /* flush */
> + ssb_read32(dev, SSB_TMSLOW);
> + udelay(1);
mystery udelay.
> +}
> +EXPORT_SYMBOL(ssb_device_disable);
>
> ...
>
> +const struct ssb_bus_ops ssb_pci_ops = {
> + .read16 = ssb_pci_read16,
> + .read32 = ssb_pci_read32,
> + .write16 = ssb_pci_write16,
> + .write32 = ssb_pci_write32,
> +};
static?
> +static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
> + struct ssb_bus *bus;
> + u16 *sprom;
> + int err = -ENODEV;
> + ssize_t count = 0;
> +
> + bus = ssb_pci_dev_to_bus(pdev);
> + if (!bus)
> + goto out;
> + err = -ENOMEM;
> + sprom = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL);
> + if (!sprom)
> + goto out;
> +
> + err = -ERESTARTSYS;
> + if (mutex_lock_interruptible(&bus->pci_sprom_mutex))
> + goto out_kfree;
> + sprom_do_read(bus, sprom);
> + mutex_unlock(&bus->pci_sprom_mutex);
> +
> + count = sprom2hex(sprom, buf, PAGE_SIZE);
> + err = 0;
> +
> +out_kfree:
> + kfree(sprom);
> +out:
> + return err ? err : count;
> +}
The mutex_lock_interruptible() looks fishy. Some commented explanation of
what it's doing would be good here. It's quite unobvious to this reader.
Cheesy deadlock avoidance? Hope not.
> +
> +/* These are the main device register access functions.
> + * do_select_core is inline to have the likely hotpath inline.
> + * All unlikely codepaths are out-of-line. */
> +static inline int do_select_core(struct ssb_bus *bus,
> + struct ssb_device *dev,
> + u16 *offset)
> +{
> + int err;
> + u8 need_seg = (*offset >= 0x800) ? 1 : 0;
> +
> + if (unlikely(dev != bus->mapped_device)) {
> + err = ssb_pcmcia_switch_core(bus, dev);
> + if (unlikely(err))
> + return err;
> + }
> + if (unlikely(need_seg != bus->mapped_pcmcia_seg)) {
> + err = ssb_pcmcia_switch_segment(bus, need_seg);
> + if (unlikely(err))
> + return err;
> + }
> + if (need_seg == 1)
> + *offset -= 0x800;
> +
> + return 0;
> +}
Looks too large for inlining.
> +const struct ssb_bus_ops ssb_pcmcia_ops = {
> + .read16 = ssb_pcmcia_read16,
> + .read32 = ssb_pcmcia_read32,
> + .write16 = ssb_pcmcia_write16,
> + .write32 = ssb_pcmcia_write32,
> +};
static?
WARNING: multiple messages have this Message-ID (diff)
From: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
To: Michael Buesch <mb-fseUSCV1ubazQB+pC5nmwQ@public.gmane.org>
Cc: "linux-kernel"
<linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
bcm43xx-dev-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Gary Zambrano <zambrano-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
Subject: Re: [PATCH] Merge the Sonics Silicon Backplane subsystem
Date: Fri, 27 Jul 2007 12:03:18 -0700 [thread overview]
Message-ID: <20070727120318.54d18cfc.akpm@linux-foundation.org> (raw)
In-Reply-To: <200707271857.24162.mb-fseUSCV1ubazQB+pC5nmwQ@public.gmane.org>
On Fri, 27 Jul 2007 18:57:20 +0200
Michael Buesch <mb-fseUSCV1ubazQB+pC5nmwQ@public.gmane.org> wrote:
> The Sonics Silicon Backplane is a mini-bus used on
> various Broadcom chips and embedded devices.
> Devices using the SSB include b44, bcm43xx and various
> Broadcom based wireless routers.
> A b44 and bcm43xx port and a SSB based OHCI driver is available.
>
hm, slim pickings for me here. Nice looking code.
checkpatch finds a few coding style glitches. Lots of 80-col violations
which you might choose ignore (comments on #defines in headers are
especially hard) but these guys:
ERROR: "foo * bar" should be "foo *bar"
#4156: FILE: drivers/ssb/ssb_private.h:119:
+extern struct ssb_bus * ssb_pci_dev_to_bus(struct pci_dev *pdev);
are worth addressing.
> ...
>
> --- /dev/null
> +++ b/drivers/ssb/driver_pcicore.c
> @@ -0,0 +1,564 @@
>
> ...
>
> +u32 pci_iobase = 0x100;
> +u32 pci_membase = SSB_PCI_DMA;
These are quite poor names for global symbols.
> +static struct resource ssb_pcicore_mem_resource = {
> + .name = "SSB PCIcore external memory",
> + .start = SSB_PCI_DMA,
> + .end = (u32)SSB_PCI_DMA + (u32)SSB_PCI_DMA_SZ - 1,
> + .flags = IORESOURCE_MEM,
> +};
start and end here are resource_size_t. Forcing them to u32 seems
inappropriate.
> +void ssb_pcicore_init(struct ssb_pcicore *pc)
Please check that all newly-added global symbols do indeed need global scope.
> +static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
> + u8 address, u16 data)
> +{
> + const u16 mdio_control = 0x128;
> + const u16 mdio_data = 0x12C;
> + u32 v;
> + int i;
> +
> + v = 0x80; /* Enable Preamble Sequence */
> + v |= 0x2; /* MDIO Clock Divisor */
> + pcicore_write32(pc, mdio_control, v);
> +
> + v = (1 << 30); /* Start of Transaction */
> + v |= (1 << 28); /* Write Transaction */
> + v |= (1 << 17); /* Turnaround */
> + v |= (u32)device << 22;
> + v |= (u32)address << 18;
> + v |= data;
> + pcicore_write32(pc, mdio_data, v);
> + udelay(10);
mystery udelays are usually worth a comment.
> + for (i = 0; i < 10; i++) {
> + v = pcicore_read32(pc, mdio_control);
> + if (v & 0x100 /* Trans complete */)
> + break;
> + msleep(1);
> + }
> + pcicore_write32(pc, mdio_control, 0);
> +}
>
> ...
>
> +
> +static void ssb_buses_lock(void)
> +{
> + if (!ssb_is_early_boot)
> + mutex_lock(&buses_mutex);
> +}
> +
> +static void ssb_buses_unlock(void)
> +{
> + if (!ssb_is_early_boot)
> + mutex_unlock(&buses_mutex);
> +}
Some comments are neeeded here to explain why we're jumping through this
hoop. It's normally OK to take a mutex early in boot, so one wonders
what's happening.
> +EXPORT_SYMBOL(ssb_clockspeed);
Please check that all newly-added exports really need to be exported (I'm
sure they do, but..)
> +static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask,
> + int timeout, int set)
> +{
> + int i;
> + u32 val;
> +
> + for (i = 0; i < timeout; i++) {
> + val = ssb_read32(dev, reg);
> + if (set) {
> + if (val & bitmask)
> + return 0;
> + } else {
> + if (!(val & bitmask))
> + return 0;
> + }
> + udelay(10);
> + }
> + printk(KERN_ERR PFX "Timeout waiting for bitmask %08X on "
> + "register %04X to %s.\n",
> + bitmask, reg, (set ? "set" : "clear"));
> +
> + return -ETIMEDOUT;
> +}
So `timeout' is in units of ten-microseconds. Unusual.
> +void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags)
> +{
> + u32 reject;
> +
> + if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_RESET)
> + return;
> +
> + reject = ssb_tmslow_reject_bitmask(dev);
> + ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK);
> + ssb_wait_bit(dev, SSB_TMSLOW, reject, 1000, 1);
> + ssb_wait_bit(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0);
> + ssb_write32(dev, SSB_TMSLOW,
> + SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
> + reject | SSB_TMSLOW_RESET |
> + core_specific_flags);
> + /* flush */
> + ssb_read32(dev, SSB_TMSLOW);
> + udelay(1);
> +
> + ssb_write32(dev, SSB_TMSLOW,
> + reject | SSB_TMSLOW_RESET |
> + core_specific_flags);
> + /* flush */
> + ssb_read32(dev, SSB_TMSLOW);
> + udelay(1);
mystery udelay.
> +}
> +EXPORT_SYMBOL(ssb_device_disable);
>
> ...
>
> +const struct ssb_bus_ops ssb_pci_ops = {
> + .read16 = ssb_pci_read16,
> + .read32 = ssb_pci_read32,
> + .write16 = ssb_pci_write16,
> + .write32 = ssb_pci_write32,
> +};
static?
> +static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
> + struct ssb_bus *bus;
> + u16 *sprom;
> + int err = -ENODEV;
> + ssize_t count = 0;
> +
> + bus = ssb_pci_dev_to_bus(pdev);
> + if (!bus)
> + goto out;
> + err = -ENOMEM;
> + sprom = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL);
> + if (!sprom)
> + goto out;
> +
> + err = -ERESTARTSYS;
> + if (mutex_lock_interruptible(&bus->pci_sprom_mutex))
> + goto out_kfree;
> + sprom_do_read(bus, sprom);
> + mutex_unlock(&bus->pci_sprom_mutex);
> +
> + count = sprom2hex(sprom, buf, PAGE_SIZE);
> + err = 0;
> +
> +out_kfree:
> + kfree(sprom);
> +out:
> + return err ? err : count;
> +}
The mutex_lock_interruptible() looks fishy. Some commented explanation of
what it's doing would be good here. It's quite unobvious to this reader.
Cheesy deadlock avoidance? Hope not.
> +
> +/* These are the main device register access functions.
> + * do_select_core is inline to have the likely hotpath inline.
> + * All unlikely codepaths are out-of-line. */
> +static inline int do_select_core(struct ssb_bus *bus,
> + struct ssb_device *dev,
> + u16 *offset)
> +{
> + int err;
> + u8 need_seg = (*offset >= 0x800) ? 1 : 0;
> +
> + if (unlikely(dev != bus->mapped_device)) {
> + err = ssb_pcmcia_switch_core(bus, dev);
> + if (unlikely(err))
> + return err;
> + }
> + if (unlikely(need_seg != bus->mapped_pcmcia_seg)) {
> + err = ssb_pcmcia_switch_segment(bus, need_seg);
> + if (unlikely(err))
> + return err;
> + }
> + if (need_seg == 1)
> + *offset -= 0x800;
> +
> + return 0;
> +}
Looks too large for inlining.
> +const struct ssb_bus_ops ssb_pcmcia_ops = {
> + .read16 = ssb_pcmcia_read16,
> + .read32 = ssb_pcmcia_read32,
> + .write16 = ssb_pcmcia_write16,
> + .write32 = ssb_pcmcia_write32,
> +};
static?
next prev parent reply other threads:[~2007-07-27 19:04 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-07-27 16:57 [PATCH] Merge the Sonics Silicon Backplane subsystem Michael Buesch
2007-07-27 16:57 ` Michael Buesch
2007-07-27 19:03 ` Andrew Morton [this message]
2007-07-27 19:03 ` Andrew Morton
2007-07-27 19:30 ` Michael Buesch
2007-07-27 19:30 ` Michael Buesch
2007-07-27 19:38 ` Andrew Morton
2007-07-27 19:38 ` Andrew Morton
2007-07-27 19:43 ` Michael Buesch
2007-07-27 19:43 ` Michael Buesch
2007-07-27 20:12 ` Andrew Morton
2007-07-27 20:12 ` Andrew Morton
2007-07-27 20:28 ` Michael Buesch
2007-07-27 20:28 ` Michael Buesch
2007-07-29 4:45 ` Dmitry Torokhov
2007-07-27 19:21 ` John W. Linville
2007-07-27 19:21 ` John W. Linville
2007-07-27 19:39 ` Michael Buesch
2007-08-02 13:58 ` Geert Uytterhoeven
2007-08-02 14:24 ` Michael Buesch
2007-08-02 14:24 ` Michael Buesch
2007-08-02 16:12 ` Geert Uytterhoeven
2007-08-02 16:18 ` Michael Buesch
2007-08-02 16:18 ` Michael Buesch
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=20070727120318.54d18cfc.akpm@linux-foundation.org \
--to=akpm@linux-foundation.org \
--cc=bcm43xx-dev@lists.berlios.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=mb@bu3sch.de \
--cc=netdev@vger.kernel.org \
--cc=zambrano@broadcom.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.