* sata_sil 3112 activity LED patch
@ 2005-07-06 2:51 Aric Cyr
2005-07-06 15:07 ` Jeff Garzik
0 siblings, 1 reply; 5+ messages in thread
From: Aric Cyr @ 2005-07-06 2:51 UTC (permalink / raw)
To: linux-kernel; +Cc: jgarzik, linux-ide
[-- Attachment #1.1: Type: text/plain, Size: 2211 bytes --]
After finally getting fed up with not having my activity light working
for my SATA drives, I came up with a small patch (more like hack) to
make it work. It works quite well, but I'm afraid that there are many
restriction that this patch does not check for that it probably
should... so consider this a work-in-progress. My information is
based on a document from Silicon Image that appears to no longer be
available on their website (Sil-AN-0082-E; 8112-0082.pdf). I still
have a copy if anyone is interested.
There are two restrictions that are not checked:
1) Is the chip a 3112 or 3114? I assume that this would only work on
a 3112, but whether it is "a bad thing" on a 3114 I do not know.
2) BAR5 + 0x54 is apparently used for the flash memory address and
data lines. However for most motherboards (i.e. not add-on cards)
with the chip, like my EPOX 8RDA3+, there is no flash memory, so
these lines are hijacked as LED GPIO. I assume that this is a
common practice for motherboard makers using the sil3112 since
Silicon Image went out of their way to produce the above mentioned
document. Anyways, the problem is that this patch does not check
if flash memory is installed or not before twiddling with the GPIO
lines. This could be extremely bad for people running the 3112
from add-on cards (or any implementation with flash memory
installed).
Setting the low 8bits at BAR5+54h seems to enable the LED circuit. It
seems that this circuit is patched through into the motherboard as it
lights the regular hard drive light on the front of my case. Setting
bits [8:15] at BAR5+54h clears the bits, disabling the LED. I hooked
this logic into the ata_bmdma_start and ata_bmdma_stop which were made
into simple wrapper functions in sata_sil.c that just set the GPIO
bits and calls ata_bmdma_*.
As a sanity test, I ran my drive, loaded, overnight with no problems.
If there is a better way to do this, I would be happy to hear any
suggestions... it is kind of ugly as it is now.
--
Aric Cyr <acyr at alumni dot uwaterloo dot ca> (http://acyr.net)
gpg fingerprint: 943A 1549 47AC D766 B7F8 D551 6703 7142 C282 D542
[-- Attachment #1.2: sata_sil-led.patch --]
[-- Type: text/plain, Size: 2117 bytes --]
--- sata_sil.c.orig 2005-06-15 17:48:23.000000000 +0900
+++ sata_sil.c 2005-07-06 01:58:28.000000000 +0900
@@ -45,6 +45,7 @@
sil_3114 = 1,
SIL_SYSCFG = 0x48,
+ SIL_GPIO = 0x54,
SIL_MASK_IDE0_INT = (1 << 22),
SIL_MASK_IDE1_INT = (1 << 23),
SIL_MASK_IDE2_INT = (1 << 24),
@@ -65,6 +66,8 @@
static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static void sil_post_set_mode (struct ata_port *ap);
+static void sil_bmdma_start(struct ata_queued_cmd *qc);
+static void sil_bmdma_stop(struct ata_port *ap);
static struct pci_device_id sil_pci_tbl[] = {
{ 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
@@ -138,8 +140,8 @@
.phy_reset = sata_phy_reset,
.post_set_mode = sil_post_set_mode,
.bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
+ .bmdma_start = sil_bmdma_start,
+ .bmdma_stop = sil_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
@@ -198,6 +200,35 @@
MODULE_DEVICE_TABLE(pci, sil_pci_tbl);
MODULE_VERSION(DRV_VERSION);
+static void sil_bmdma_start(struct ata_queued_cmd *qc)
+{
+ void* mmio_base = qc->ap->host_set->mmio_base;
+ u32 gpio = readl(mmio_base + SIL_GPIO);
+
+ /* setting the lower 8 bits to activate the activity LED */
+ gpio |= 0x00ff;
+ writel(gpio, mmio_base + SIL_GPIO);
+ readl(mmio_base + SIL_GPIO); /* flush */
+
+ ata_bmdma_start(qc);
+}
+
+static void sil_bmdma_stop(struct ata_port *ap)
+{
+ void* mmio_base = ap->host_set->mmio_base;
+ u32 gpio = readl(mmio_base + SIL_GPIO);
+
+ ata_bmdma_stop(ap);
+
+ /*
+ * setting bits [8:15] clears the lower 8 bits,
+ * deactivating the activity LED
+ */
+ gpio |= 0xff00;
+ writel(gpio, mmio_base + SIL_GPIO);
+ readl(mmio_base + SIL_GPIO); /* flush */
+}
+
static void sil_post_set_mode (struct ata_port *ap)
{
struct ata_host_set *host_set = ap->host_set;
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: sata_sil 3112 activity LED patch
2005-07-06 2:51 sata_sil 3112 activity LED patch Aric Cyr
@ 2005-07-06 15:07 ` Jeff Garzik
2005-07-07 12:47 ` Jens Axboe
0 siblings, 1 reply; 5+ messages in thread
From: Jeff Garzik @ 2005-07-06 15:07 UTC (permalink / raw)
To: Aric Cyr; +Cc: linux-kernel, linux-ide
Aric Cyr wrote:
> After finally getting fed up with not having my activity light working
> for my SATA drives, I came up with a small patch (more like hack) to
> make it work. It works quite well, but I'm afraid that there are many
> restriction that this patch does not check for that it probably
> should... so consider this a work-in-progress. My information is
> based on a document from Silicon Image that appears to no longer be
> available on their website (Sil-AN-0082-E; 8112-0082.pdf). I still
> have a copy if anyone is interested.
>
> There are two restrictions that are not checked:
>
> 1) Is the chip a 3112 or 3114? I assume that this would only work on
> a 3112, but whether it is "a bad thing" on a 3114 I do not know.
>
> 2) BAR5 + 0x54 is apparently used for the flash memory address and
> data lines. However for most motherboards (i.e. not add-on cards)
> with the chip, like my EPOX 8RDA3+, there is no flash memory, so
> these lines are hijacked as LED GPIO. I assume that this is a
> common practice for motherboard makers using the sil3112 since
> Silicon Image went out of their way to produce the above mentioned
> document. Anyways, the problem is that this patch does not check
> if flash memory is installed or not before twiddling with the GPIO
> lines. This could be extremely bad for people running the 3112
> from add-on cards (or any implementation with flash memory
> installed).
>
> Setting the low 8bits at BAR5+54h seems to enable the LED circuit. It
> seems that this circuit is patched through into the motherboard as it
> lights the regular hard drive light on the front of my case. Setting
> bits [8:15] at BAR5+54h clears the bits, disabling the LED. I hooked
> this logic into the ata_bmdma_start and ata_bmdma_stop which were made
> into simple wrapper functions in sata_sil.c that just set the GPIO
> bits and calls ata_bmdma_*.
I don't think its ugly, necessarily. I do worry about the flash memory
stuff, though, which is why I don't want to merge this upstream for now.
For your patch specifically, it would be nice to follow the coding style
that is found in the rest of the driver (single-tab indents, etc., read
CodingStyle in kernel source tree).
Jeff
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: sata_sil 3112 activity LED patch
2005-07-06 15:07 ` Jeff Garzik
@ 2005-07-07 12:47 ` Jens Axboe
2005-07-07 14:23 ` Aric Cyr
0 siblings, 1 reply; 5+ messages in thread
From: Jens Axboe @ 2005-07-07 12:47 UTC (permalink / raw)
To: Jeff Garzik; +Cc: Aric Cyr, linux-kernel, linux-ide
On Wed, Jul 06 2005, Jeff Garzik wrote:
> Aric Cyr wrote:
> >After finally getting fed up with not having my activity light working
> >for my SATA drives, I came up with a small patch (more like hack) to
> >make it work. It works quite well, but I'm afraid that there are many
> >restriction that this patch does not check for that it probably
> >should... so consider this a work-in-progress. My information is
> >based on a document from Silicon Image that appears to no longer be
> >available on their website (Sil-AN-0082-E; 8112-0082.pdf). I still
> >have a copy if anyone is interested.
> >
> >There are two restrictions that are not checked:
> >
> >1) Is the chip a 3112 or 3114? I assume that this would only work on
> > a 3112, but whether it is "a bad thing" on a 3114 I do not know.
> >
> >2) BAR5 + 0x54 is apparently used for the flash memory address and
> > data lines. However for most motherboards (i.e. not add-on cards)
> > with the chip, like my EPOX 8RDA3+, there is no flash memory, so
> > these lines are hijacked as LED GPIO. I assume that this is a
> > common practice for motherboard makers using the sil3112 since
> > Silicon Image went out of their way to produce the above mentioned
> > document. Anyways, the problem is that this patch does not check
> > if flash memory is installed or not before twiddling with the GPIO
> > lines. This could be extremely bad for people running the 3112
> > from add-on cards (or any implementation with flash memory
> > installed).
> >
> >Setting the low 8bits at BAR5+54h seems to enable the LED circuit. It
> >seems that this circuit is patched through into the motherboard as it
> >lights the regular hard drive light on the front of my case. Setting
> >bits [8:15] at BAR5+54h clears the bits, disabling the LED. I hooked
> >this logic into the ata_bmdma_start and ata_bmdma_stop which were made
> >into simple wrapper functions in sata_sil.c that just set the GPIO
> >bits and calls ata_bmdma_*.
>
> I don't think its ugly, necessarily. I do worry about the flash memory
> stuff, though, which is why I don't want to merge this upstream for now.
>
> For your patch specifically, it would be nice to follow the coding style
> that is found in the rest of the driver (single-tab indents, etc., read
> CodingStyle in kernel source tree).
There's also an existing variant of this in the block layer, the
activity_fn, that we use on the ibook/powerbook to use the sleep led as
an activity light. Just in case you prefer that to overloading the bmdma
start/stop handlers.
--
Jens Axboe
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: sata_sil 3112 activity LED patch
2005-07-07 12:47 ` Jens Axboe
@ 2005-07-07 14:23 ` Aric Cyr
2005-07-07 15:11 ` Jens Axboe
0 siblings, 1 reply; 5+ messages in thread
From: Aric Cyr @ 2005-07-07 14:23 UTC (permalink / raw)
To: Jens Axboe; +Cc: Jeff Garzik, linux-kernel, linux-ide
[-- Attachment #1.1: Type: text/plain, Size: 1996 bytes --]
On Thu, Jul 07, 2005 at 02:47:03PM +0200, Jens Axboe wrote:
> On Wed, Jul 06 2005, Jeff Garzik wrote:
> > I don't think its ugly, necessarily. I do worry about the flash memory
> > stuff, though, which is why I don't want to merge this upstream for now.
> >
> > For your patch specifically, it would be nice to follow the coding style
> > that is found in the rest of the driver (single-tab indents, etc., read
> > CodingStyle in kernel source tree).
I cleaned it up... it got quite a bit larger since I am attempting to
check for valid usage. Unfortunately I do not know if the 3114 has a
similar GPIO mechanism, nor do I have an add on card with a 3112 to
verify with. My new/improved patch is attached, tested on my system
with 2.6.12.
If anyone with either such devices could test (with caution!) I'd like
to hear the results. Alternatively, I'd be interested in the value of
the MMIO register at BASE_ADDRESS_5 + 0x54 before the driver is
loaded.
> There's also an existing variant of this in the block layer, the
> activity_fn, that we use on the ibook/powerbook to use the sleep led as
> an activity light. Just in case you prefer that to overloading the bmdma
> start/stop handlers.
You suggestion at first looked to be incredibly nice... until I looked
at how much implementation was required. I am considering trying it,
but I cannot find a place for an sata driver to call the
blk_queue_activity_fn() with meaningful parameters during init.
On a second look, I guess I would have to override
ata_scsi_slave_config() in the driver and hook up the activity light
there. This would be fine I guess. Unless I am interpreting this
incorrectly, however, I would need to use a timer or something to turn
the light back off? I'm probably missing something, so is there a
simpler way to do this?
--
Aric Cyr <acyr at alumni dot uwaterloo dot ca> (http://acyr.net)
gpg fingerprint: 943A 1549 47AC D766 B7F8 D551 6703 7142 C282 D542
[-- Attachment #1.2: sata_sil-led.patch --]
[-- Type: text/plain, Size: 4246 bytes --]
--- drivers/scsi/sata_sil.c.orig 2005-07-07 10:07:19.000000000 +0900
+++ drivers/scsi/sata_sil.c 2005-07-07 23:19:36.000000000 +0900
@@ -54,6 +54,7 @@
SIL_FIFO_W3 = 0x245,
SIL_SYSCFG = 0x48,
+ SIL_GPIO = 0x54,
SIL_MASK_IDE0_INT = (1 << 22),
SIL_MASK_IDE1_INT = (1 << 23),
SIL_MASK_IDE2_INT = (1 << 24),
@@ -74,6 +75,9 @@
static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static void sil_post_set_mode (struct ata_port *ap);
+static void sil_bmdma_start(struct ata_queued_cmd *qc);
+static void sil_bmdma_stop(struct ata_port *ap);
+static void sil_host_stop (struct ata_host_set *host_set);
static struct pci_device_id sil_pci_tbl[] = {
{ 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
@@ -149,8 +152,8 @@
.phy_reset = sata_phy_reset,
.post_set_mode = sil_post_set_mode,
.bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
+ .bmdma_start = sil_bmdma_start,
+ .bmdma_stop = sil_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
@@ -161,7 +164,7 @@
.scr_write = sil_scr_write,
.port_start = ata_port_start,
.port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
+ .host_stop = sil_host_stop,
};
static struct ata_port_info sil_port_info[] = {
@@ -204,6 +207,10 @@
/* ... port 3 */
};
+struct sil_host_priv {
+ u8 use_gpio;
+};
+
MODULE_AUTHOR("Jeff Garzik");
MODULE_DESCRIPTION("low-level driver for Silicon Image SATA controller");
MODULE_LICENSE("GPL");
@@ -217,6 +224,48 @@
return cache_line;
}
+static void sil_bmdma_start(struct ata_queued_cmd *qc)
+{
+ struct sil_host_priv* hpriv = qc->ap->host_set->private_data;
+ if (hpriv->use_gpio) {
+ void* mmio_base = qc->ap->host_set->mmio_base;
+ u32 gpio = readl(mmio_base + SIL_GPIO);
+
+ /* set the lower 8 bits to activate the LED */
+ gpio |= 0xff;
+ writel(gpio, mmio_base + SIL_GPIO);
+ readl(mmio_base + SIL_GPIO); /* flush */
+ }
+
+ ata_bmdma_start(qc);
+}
+
+static void sil_bmdma_stop(struct ata_port *ap)
+{
+ struct sil_host_priv* hpriv = ap->host_set->private_data;
+
+ ata_bmdma_stop(ap);
+
+ if (hpriv->use_gpio) {
+ void* mmio_base = ap->host_set->mmio_base;
+ u32 gpio = readl(mmio_base + SIL_GPIO);
+
+ /* set bits [15:8] to disable the LED */
+ gpio |= 0xff00;
+ writel(gpio, mmio_base + SIL_GPIO);
+ readl(mmio_base + SIL_GPIO); /* flush */
+ }
+}
+
+static void sil_host_stop (struct ata_host_set *host_set)
+{
+ if (host_set->private_data)
+ kfree(host_set->private_data);
+
+ ata_host_stop(host_set);
+}
+
+
static void sil_post_set_mode (struct ata_port *ap)
{
struct ata_host_set *host_set = ap->host_set;
@@ -353,6 +402,7 @@
{
static int printed_version;
struct ata_probe_ent *probe_ent = NULL;
+ struct sil_host_priv *hpriv = NULL;
unsigned long base;
void *mmio_base;
int rc;
@@ -391,6 +441,13 @@
goto err_out_regions;
}
+ hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL);
+ if (!hpriv) {
+ rc = -ENOMEM;
+ goto err_out_free_ent;
+ }
+ memset(hpriv, 0, sizeof(*hpriv));
+
memset(probe_ent, 0, sizeof(*probe_ent));
INIT_LIST_HEAD(&probe_ent->node);
probe_ent->dev = pci_dev_to_dev(pdev);
@@ -408,10 +465,11 @@
pci_resource_len(pdev, 5));
if (mmio_base == NULL) {
rc = -ENOMEM;
- goto err_out_free_ent;
+ goto err_out_free_hpriv;
}
probe_ent->mmio_base = mmio_base;
+ probe_ent->private_data = hpriv;
base = (unsigned long) mmio_base;
@@ -456,6 +514,12 @@
irq_mask = SIL_MASK_2PORT;
}
+ /* check for LED GPIO on 3112 parts */
+ tmp = readl(mmio_base + SIL_GPIO);
+ if ((ent->driver_data == sil_3112) && ((tmp & 0xff) == 0xff)) {
+ hpriv->use_gpio = 1;
+ }
+
/* make sure IDE0/1/2/3 interrupts are not masked */
tmp = readl(mmio_base + SIL_SYSCFG);
if (tmp & irq_mask) {
@@ -477,6 +541,8 @@
return 0;
+err_out_free_hpriv:
+ kfree(hpriv);
err_out_free_ent:
kfree(probe_ent);
err_out_regions:
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: sata_sil 3112 activity LED patch
2005-07-07 14:23 ` Aric Cyr
@ 2005-07-07 15:11 ` Jens Axboe
0 siblings, 0 replies; 5+ messages in thread
From: Jens Axboe @ 2005-07-07 15:11 UTC (permalink / raw)
To: Aric Cyr; +Cc: Jeff Garzik, linux-kernel, linux-ide
On Thu, Jul 07 2005, Aric Cyr wrote:
> > There's also an existing variant of this in the block layer, the
> > activity_fn, that we use on the ibook/powerbook to use the sleep led as
> > an activity light. Just in case you prefer that to overloading the bmdma
> > start/stop handlers.
>
> You suggestion at first looked to be incredibly nice... until I looked
> at how much implementation was required. I am considering trying it,
> but I cannot find a place for an sata driver to call the
> blk_queue_activity_fn() with meaningful parameters during init.
>
> On a second look, I guess I would have to override
> ata_scsi_slave_config() in the driver and hook up the activity light
> there. This would be fine I guess. Unless I am interpreting this
> incorrectly, however, I would need to use a timer or something to turn
> the light back off? I'm probably missing something, so is there a
> simpler way to do this?
Hmm yes, it will require more work for you. It should be cleaned up a
little to pass in a START/STOP variable and handle everything in the
block layer instead. You probably just want to continue using the bmdma
hooks now, that is actually a fine implementation imo.
--
Jens Axboe
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2005-07-07 15:09 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-07-06 2:51 sata_sil 3112 activity LED patch Aric Cyr
2005-07-06 15:07 ` Jeff Garzik
2005-07-07 12:47 ` Jens Axboe
2005-07-07 14:23 ` Aric Cyr
2005-07-07 15:11 ` Jens Axboe
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).