* [PATCHSET] libata: improve initialization and legacy handling
@ 2006-08-01 20:11 Tejun Heo
2006-08-01 20:11 ` [PATCH 05/11] libata: fix ata_device_add() error path Tejun Heo
` (11 more replies)
0 siblings, 12 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-01 20:11 UTC (permalink / raw)
To: jgarzik, alan
Hello, all.
This patchset contains patches from Jeff Garzik, Alan Cox, Dave Jones
and me to fix/clean up initializaton and legacy handling. This
patchset contains the following patches.
#01-05 : assorted fixes & clean ups to initiallization
#06-07 : kill host_set->next and handle legacy ports in one host_set
#08-11 : use dummy port for stolen legacy ports and kill hard_port_no
Tested both combined and native modes with ICH7R. Everything seems to
work including stolen port handling.
This patchset is against the current libata-dev #upstream[1] and
available in the following git tree.
http://htj.dyndns.org/git/?p=libata-tj.git;a=shortlog;h=tj-upstream
git://htj.dyndns.org/libata-tj tj-upstream
PATA drivers have been updated accordingly and available at
http://htj.dyndns.org/git/?p=libata-tj.git;a=shortlog;h=tj-pata-drivers
git://htj.dyndns.org/libata-tj tj-pata-drivers
Updated ALL branch is available at
http://htj.dyndns.org/git/?p=libata-tj.git;a=shortlog;h=tj-ALL
git://htj.dyndns.org/libata-tj tj-ALL
I'll post PATA patch separately for review.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 05/11] libata: fix ata_device_add() error path
2006-08-01 20:11 [PATCHSET] libata: improve initialization and legacy handling Tejun Heo
@ 2006-08-01 20:11 ` Tejun Heo
2006-08-01 20:11 ` [PATCH 04/11] [libata] Kill 'count' var in ata_device_add() Tejun Heo
` (10 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-01 20:11 UTC (permalink / raw)
To: jgarzik, alan; +Cc: Tejun Heo
In the error path, ata_device_add()
* dereferences null host_set->ports[] element.
* calls scsi_remove_host() on not-yet-added shost.
This patch fixes both bugs. The first problem was spotted and initial
patch submitted by Dave Jones <davej@redhat.com>. The second problem
was mentioned and fixed by Jeff Garzik <jgarzik@pobox.com> in a larger
cleanup patch.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Cc: Dave Jones <davej@redhat.com>
Cc: Jeff Garzik <jgarzik@pobox.com>
---
drivers/scsi/libata-core.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
4d1a48cb2671959685bdeef6d186727b9cfeee10
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index fdcc58e..96fc7a5 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5505,10 +5505,10 @@ int ata_device_add(const struct ata_prob
err_out:
for (i = 0; i < host_set->n_ports; i++) {
struct ata_port *ap = host_set->ports[i];
-
- scsi_remove_host(ap->host);
- ap->ops->port_stop(ap);
- scsi_host_put(ap->host);
+ if (ap) {
+ ap->ops->port_stop(ap);
+ scsi_host_put(ap->host);
+ }
}
kfree(host_set);
--
1.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 01/11] ata_piix: fix host_set private_data intialization
2006-08-01 20:11 [PATCHSET] libata: improve initialization and legacy handling Tejun Heo
` (2 preceding siblings ...)
2006-08-01 20:11 ` [PATCH 02/11] [libata] some function renaming Tejun Heo
@ 2006-08-01 20:11 ` Tejun Heo
2006-08-01 20:11 ` [PATCH 03/11] [libata] manually inline ata_host_remove() Tejun Heo
` (7 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-01 20:11 UTC (permalink / raw)
To: jgarzik, alan; +Cc: Tejun Heo
To get host_set->private_data initialized reliably, all pinfos need to
point to the same hpriv. Restore pinfo->private_data after pata pinfo
assignment.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/scsi/ata_piix.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
2b9e1bbec0f99f038e40d040a41a082154399554
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 19745a3..298e464 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -828,6 +828,7 @@ static void __devinit piix_init_sata_map
case IDE:
WARN_ON((i & 1) || map[i + 1] != IDE);
pinfo[i / 2] = piix_port_info[ich5_pata];
+ pinfo[i / 2].private_data = hpriv;
i++;
printk(" IDE IDE");
break;
--
1.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 03/11] [libata] manually inline ata_host_remove()
2006-08-01 20:11 [PATCHSET] libata: improve initialization and legacy handling Tejun Heo
` (3 preceding siblings ...)
2006-08-01 20:11 ` [PATCH 01/11] ata_piix: fix host_set private_data intialization Tejun Heo
@ 2006-08-01 20:11 ` Tejun Heo
2006-08-01 20:11 ` [PATCH 06/11] libata: rework legacy handling to remove much of the cruft Tejun Heo
` (6 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-01 20:11 UTC (permalink / raw)
To: jgarzik, alan; +Cc: Jeff Garzik, Tejun Heo
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/scsi/libata-core.c | 31 ++++++-------------------------
1 files changed, 6 insertions(+), 25 deletions(-)
2807702eafe33dd1783fd39c7137376082521736
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 1cc12d4..4e06edc 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5185,28 +5185,6 @@ void ata_host_stop (struct ata_host_set
iounmap(host_set->mmio_base);
}
-
-/**
- * ata_host_remove - Unregister SCSI host structure with upper layers
- * @ap: Port to unregister
- * @do_unregister: 1 if we fully unregister, 0 to just stop the port
- *
- * LOCKING:
- * Inherited from caller.
- */
-
-static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister)
-{
- struct Scsi_Host *sh = ap->host;
-
- DPRINTK("ENTER\n");
-
- if (do_unregister)
- scsi_remove_host(sh);
-
- ap->ops->port_stop(ap);
-}
-
/**
* ata_dev_init - Initialize an ata_device structure
* @dev: Device structure to initialize
@@ -5532,8 +5510,11 @@ int ata_device_add(const struct ata_prob
err_out:
for (i = 0; i < count; i++) {
- ata_host_remove(host_set->ports[i], 1);
- scsi_host_put(host_set->ports[i]->host);
+ struct ata_port *ap = host_set->ports[i];
+
+ scsi_remove_host(ap->host);
+ ap->ops->port_stop(ap);
+ scsi_host_put(ap->host);
}
err_free_ret:
kfree(host_set);
@@ -5662,7 +5643,7 @@ int ata_scsi_release(struct Scsi_Host *h
DPRINTK("ENTER\n");
ap->ops->port_disable(ap);
- ata_host_remove(ap, 0);
+ ap->ops->port_stop(ap);
DPRINTK("EXIT\n");
return 1;
--
1.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 04/11] [libata] Kill 'count' var in ata_device_add()
2006-08-01 20:11 [PATCHSET] libata: improve initialization and legacy handling Tejun Heo
2006-08-01 20:11 ` [PATCH 05/11] libata: fix ata_device_add() error path Tejun Heo
@ 2006-08-01 20:11 ` Tejun Heo
2006-08-01 20:11 ` [PATCH 02/11] [libata] some function renaming Tejun Heo
` (9 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-01 20:11 UTC (permalink / raw)
To: jgarzik, alan; +Cc: Jeff Garzik, Tejun Heo
Eliminate redundant loop variable 'count'
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/scsi/libata-core.c | 20 +++++++-------------
1 files changed, 7 insertions(+), 13 deletions(-)
bbf12ff2c1007f7c1275d7e5b44db8217af30cf2
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 4e06edc..fdcc58e 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5370,7 +5370,7 @@ err_out:
*/
int ata_device_add(const struct ata_probe_ent *ent)
{
- unsigned int count = 0, i;
+ unsigned int i;
struct device *dev = ent->dev;
struct ata_host_set *host_set;
int rc;
@@ -5392,7 +5392,7 @@ int ata_device_add(const struct ata_prob
host_set->flags = ent->host_set_flags;
/* register each port bound to this device */
- for (i = 0; i < ent->n_ports; i++) {
+ for (i = 0; i < host_set->n_ports; i++) {
struct ata_port *ap;
unsigned long xfer_mode_mask;
@@ -5418,12 +5418,8 @@ int ata_device_add(const struct ata_prob
ata_chk_status(ap);
host_set->ops->irq_clear(ap);
ata_eh_freeze_port(ap); /* freeze port before requesting IRQ */
- count++;
}
- if (!count)
- goto err_free_ret;
-
/* obtain irq, that is shared between channels */
rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
DRV_NAME, host_set);
@@ -5435,13 +5431,11 @@ int ata_device_add(const struct ata_prob
/* perform each probe synchronously */
DPRINTK("probe begin\n");
- for (i = 0; i < count; i++) {
- struct ata_port *ap;
+ for (i = 0; i < host_set->n_ports; i++) {
+ struct ata_port *ap = host_set->ports[i];
u32 scontrol;
int rc;
- ap = host_set->ports[i];
-
/* init sata_spd_limit to the current value */
if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
int spd = (scontrol >> 4) & 0xf;
@@ -5497,7 +5491,7 @@ int ata_device_add(const struct ata_prob
/* probes are done, now scan each port's disk(s) */
DPRINTK("host probe begin\n");
- for (i = 0; i < count; i++) {
+ for (i = 0; i < host_set->n_ports; i++) {
struct ata_port *ap = host_set->ports[i];
ata_scsi_scan_host(ap);
@@ -5509,14 +5503,14 @@ int ata_device_add(const struct ata_prob
return ent->n_ports; /* success */
err_out:
- for (i = 0; i < count; i++) {
+ for (i = 0; i < host_set->n_ports; i++) {
struct ata_port *ap = host_set->ports[i];
scsi_remove_host(ap->host);
ap->ops->port_stop(ap);
scsi_host_put(ap->host);
}
-err_free_ret:
+
kfree(host_set);
VPRINTK("EXIT, returning 0\n");
return 0;
--
1.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 02/11] [libata] some function renaming
2006-08-01 20:11 [PATCHSET] libata: improve initialization and legacy handling Tejun Heo
2006-08-01 20:11 ` [PATCH 05/11] libata: fix ata_device_add() error path Tejun Heo
2006-08-01 20:11 ` [PATCH 04/11] [libata] Kill 'count' var in ata_device_add() Tejun Heo
@ 2006-08-01 20:11 ` Tejun Heo
2006-08-01 20:11 ` [PATCH 01/11] ata_piix: fix host_set private_data intialization Tejun Heo
` (8 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-01 20:11 UTC (permalink / raw)
To: jgarzik, alan; +Cc: Jeff Garzik, Tejun Heo
s/ata_host_add/ata_port_add/
s/ata_host_init/ata_port_init/
libata naming got stuck in the middle of a Great Renaming:
ata_host -> ata_port
ata_host_set -> ata_host
To eliminate confusion, let's just give up for now, and simply ensure
that things are internally consistent.
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/scsi/libata-core.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
dd8e6d7b6e5070c28359ed41bd876e2051672aff
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 66feebd..1cc12d4 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5240,7 +5240,7 @@ void ata_dev_init(struct ata_device *dev
}
/**
- * ata_host_init - Initialize an ata_port structure
+ * ata_port_init - Initialize an ata_port structure
* @ap: Structure to initialize
* @host: associated SCSI mid-layer structure
* @host_set: Collection of hosts to which @ap belongs
@@ -5253,7 +5253,7 @@ void ata_dev_init(struct ata_device *dev
* LOCKING:
* Inherited from caller.
*/
-static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
+static void ata_port_init(struct ata_port *ap, struct Scsi_Host *host,
struct ata_host_set *host_set,
const struct ata_probe_ent *ent, unsigned int port_no)
{
@@ -5320,7 +5320,7 @@ #endif
}
/**
- * ata_host_add - Attach low-level ATA driver to system
+ * ata_port_add - Attach low-level ATA driver to system
* @ent: Information provided by low-level driver
* @host_set: Collections of ports to which we add
* @port_no: Port number associated with this host
@@ -5334,7 +5334,7 @@ #endif
* New ata_port on success, for NULL on error.
*/
-static struct ata_port * ata_host_add(const struct ata_probe_ent *ent,
+static struct ata_port * ata_port_add(const struct ata_probe_ent *ent,
struct ata_host_set *host_set,
unsigned int port_no)
{
@@ -5359,7 +5359,7 @@ static struct ata_port * ata_host_add(co
ap = ata_shost_to_port(host);
- ata_host_init(ap, host, host_set, ent, port_no);
+ ata_port_init(ap, host, host_set, ent, port_no);
rc = ap->ops->port_start(ap);
if (rc)
@@ -5418,7 +5418,7 @@ int ata_device_add(const struct ata_prob
struct ata_port *ap;
unsigned long xfer_mode_mask;
- ap = ata_host_add(ent, host_set, i);
+ ap = ata_port_add(ent, host_set, i);
if (!ap)
goto err_out;
--
1.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 08/11] libata: implement dummy port
2006-08-01 20:11 [PATCHSET] libata: improve initialization and legacy handling Tejun Heo
` (5 preceding siblings ...)
2006-08-01 20:11 ` [PATCH 06/11] libata: rework legacy handling to remove much of the cruft Tejun Heo
@ 2006-08-01 20:11 ` Tejun Heo
2006-08-01 20:11 ` [PATCH 07/11] libata: fix several bugs in reworked legacy handling Tejun Heo
` (4 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-01 20:11 UTC (permalink / raw)
To: jgarzik, alan; +Cc: Tejun Heo
Implement dummy port which can be requested by setting appropriate bit
in probe_ent->dummy_port_mask. The dummy port is used as placeholder
for stolen legacy port. This allows libata to guarantee that
index_of(ap) == ap->port_no == actual_device_port_no, and thus to
remove error-prone ap->hard_port_no.
As it's used only when one port of a legacy controller is reserved by
some other entity (e.g. IDE), the focus is on keeping the added *code*
complexity at minimum, so dummy port allocates all libata core
resources and acts as a normal port. It just has all dummy port_ops.
This patch only implements dummy port. The following patch will make
libata use it for stolen legacy ports.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/scsi/libata-core.c | 61 +++++++++++++++++++++++++++++++++++++-------
include/linux/libata.h | 3 ++
2 files changed, 54 insertions(+), 10 deletions(-)
d9efe31ff5eda88172278153c15a8fd5d0f94ec5
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index fe23738..fffb38a 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5311,7 +5311,6 @@ static struct ata_port * ata_port_add(co
{
struct Scsi_Host *host;
struct ata_port *ap;
- int rc;
DPRINTK("ENTER\n");
@@ -5332,15 +5331,7 @@ static struct ata_port * ata_port_add(co
ata_port_init(ap, host, host_set, ent, port_no);
- rc = ap->ops->port_start(ap);
- if (rc)
- goto err_out;
-
return ap;
-
-err_out:
- scsi_host_put(host);
- return NULL;
}
/**
@@ -5395,11 +5386,27 @@ int ata_device_add(const struct ata_prob
if (!ap)
goto err_out;
+ host_set->ports[i] = ap;
+
+ /* dummy? */
+ if (ent->dummy_port_mask & (1 << i)) {
+ ata_port_printk(ap, KERN_INFO, "DUMMY\n");
+ ap->ops = &ata_dummy_port_ops;
+ continue;
+ }
+
+ /* start port */
+ rc = ap->ops->port_start(ap);
+ if (rc) {
+ host_set->ports[i] = NULL;
+ scsi_host_put(ap->host);
+ goto err_out;
+ }
+
/* Report the secondary IRQ for second channel legacy */
if (i == 1 && ent->irq2)
irq_line = ent->irq2;
- host_set->ports[i] = ap;
xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) |
(ap->mwdma_mask << ATA_SHIFT_MWDMA) |
(ap->pio_mask << ATA_SHIFT_PIO);
@@ -5895,6 +5902,39 @@ u32 ata_wait_register(void __iomem *reg,
}
/*
+ * Dummy port_ops
+ */
+static void ata_dummy_noret(struct ata_port *ap) { }
+static int ata_dummy_ret0(struct ata_port *ap) { return 0; }
+static void ata_dummy_qc_noret(struct ata_queued_cmd *qc) { }
+
+static u8 ata_dummy_check_status(struct ata_port *ap)
+{
+ return ATA_DRDY;
+}
+
+static unsigned int ata_dummy_qc_issue(struct ata_queued_cmd *qc)
+{
+ return AC_ERR_SYSTEM;
+}
+
+const struct ata_port_operations ata_dummy_port_ops = {
+ .port_disable = ata_port_disable,
+ .check_status = ata_dummy_check_status,
+ .check_altstatus = ata_dummy_check_status,
+ .dev_select = ata_noop_dev_select,
+ .qc_prep = ata_noop_qc_prep,
+ .qc_issue = ata_dummy_qc_issue,
+ .freeze = ata_dummy_noret,
+ .thaw = ata_dummy_noret,
+ .error_handler = ata_dummy_noret,
+ .post_internal_cmd = ata_dummy_qc_noret,
+ .irq_clear = ata_dummy_noret,
+ .port_start = ata_dummy_ret0,
+ .port_stop = ata_dummy_noret,
+};
+
+/*
* libata is essentially a library of internal helper functions for
* low-level ATA host controller drivers. As such, the API/ABI is
* likely to change as new drivers are added and updated.
@@ -5904,6 +5944,7 @@ u32 ata_wait_register(void __iomem *reg,
EXPORT_SYMBOL_GPL(sata_deb_timing_normal);
EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug);
EXPORT_SYMBOL_GPL(sata_deb_timing_long);
+EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
EXPORT_SYMBOL_GPL(ata_std_bios_param);
EXPORT_SYMBOL_GPL(ata_std_ports);
EXPORT_SYMBOL_GPL(ata_device_add);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 9a94778..10c5587 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -353,6 +353,7 @@ struct ata_probe_ent {
struct ata_ioports port[ATA_MAX_PORTS];
unsigned int n_ports;
unsigned int hard_port_no;
+ unsigned int dummy_port_mask;
unsigned int pio_mask;
unsigned int mwdma_mask;
unsigned int udma_mask;
@@ -652,6 +653,8 @@ extern const unsigned long sata_deb_timi
extern const unsigned long sata_deb_timing_hotplug[];
extern const unsigned long sata_deb_timing_long[];
+extern const struct ata_port_operations ata_dummy_port_ops;
+
static inline const unsigned long *
sata_ehc_deb_timing(struct ata_eh_context *ehc)
{
--
1.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 06/11] libata: rework legacy handling to remove much of the cruft
2006-08-01 20:11 [PATCHSET] libata: improve initialization and legacy handling Tejun Heo
` (4 preceding siblings ...)
2006-08-01 20:11 ` [PATCH 03/11] [libata] manually inline ata_host_remove() Tejun Heo
@ 2006-08-01 20:11 ` Tejun Heo
2006-08-01 20:11 ` [PATCH 08/11] libata: implement dummy port Tejun Heo
` (5 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-01 20:11 UTC (permalink / raw)
To: jgarzik; +Cc: Alan Cox, Alan Cox, Andrew Morton, Tejun Heo
Kill host_set->next
Fix simplex support
Allow per platform setting of IDE legacy bases
Turn per device tuning on so that PATA timings are fully enabled
Some of this can be tidied further later on, in particular all the
legacy port gunge belongs as a PCI quirk/PCI header decode to understand
the special legacy IDE rules in the PCI spec.
Longer term Jeff also wants to move the request_irq/free_irq out of core
which will make this even cleaner.
(tj: folded in two followup patches - ata_piix fix & broken arch fix -
as compilation fails without those)
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/scsi/ata_piix.c | 2 -
drivers/scsi/libata-bmdma.c | 136 ++++++++++++++++------------------
drivers/scsi/libata-core.c | 85 +++++++++++----------
include/asm-alpha/libata-portmap.h | 1
include/asm-generic/libata-portmap.h | 12 +++
include/asm-i386/libata-portmap.h | 1
include/asm-ia64/libata-portmap.h | 1
include/asm-powerpc/libata-portmap.h | 1
include/asm-sparc/libata-portmap.h | 1
include/asm-sparc64/libata-portmap.h | 1
include/asm-x86_64/libata-portmap.h | 1
include/linux/libata.h | 5 +
12 files changed, 131 insertions(+), 116 deletions(-)
create mode 100644 include/asm-alpha/libata-portmap.h
create mode 100644 include/asm-generic/libata-portmap.h
create mode 100644 include/asm-i386/libata-portmap.h
create mode 100644 include/asm-ia64/libata-portmap.h
create mode 100644 include/asm-powerpc/libata-portmap.h
create mode 100644 include/asm-sparc/libata-portmap.h
create mode 100644 include/asm-sparc64/libata-portmap.h
create mode 100644 include/asm-x86_64/libata-portmap.h
82eb6080612915979d1f3aa6eaaa918998b2d948
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 298e464..dfdf4a7 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -932,8 +932,6 @@ static int piix_init_one (struct pci_dev
static void piix_host_stop(struct ata_host_set *host_set)
{
- if (host_set->next == NULL)
- kfree(host_set->private_data);
ata_host_stop(host_set);
}
diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c
index 9ce221f..34343e5 100644
--- a/drivers/scsi/libata-bmdma.c
+++ b/drivers/scsi/libata-bmdma.c
@@ -880,7 +880,7 @@ ata_pci_init_native_mode(struct pci_dev
if (bmdma) {
bmdma += 8;
if(inb(bmdma + 2) & 0x80)
- probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
+ probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
probe_ent->port[p].bmdma_addr = bmdma;
}
ata_std_ports(&probe_ent->port[p]);
@@ -893,45 +893,55 @@ ata_pci_init_native_mode(struct pci_dev
static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
- struct ata_port_info *port, int port_num)
+ struct ata_port_info **port, int port_mask)
{
struct ata_probe_ent *probe_ent;
- unsigned long bmdma;
+ unsigned long bmdma = pci_resource_start(pdev, 4);
+
+ int port_num = 0;
- probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port);
+ probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
if (!probe_ent)
return NULL;
probe_ent->legacy_mode = 1;
probe_ent->n_ports = 1;
- probe_ent->hard_port_no = port_num;
- probe_ent->private_data = port->private_data;
-
- switch(port_num)
- {
- case 0:
- probe_ent->irq = 14;
- probe_ent->port[0].cmd_addr = 0x1f0;
- probe_ent->port[0].altstatus_addr =
- probe_ent->port[0].ctl_addr = 0x3f6;
- break;
- case 1:
- probe_ent->irq = 15;
- probe_ent->port[0].cmd_addr = 0x170;
- probe_ent->port[0].altstatus_addr =
- probe_ent->port[0].ctl_addr = 0x376;
- break;
- }
+ probe_ent->hard_port_no = 0;
+ probe_ent->private_data = port[0]->private_data;
- bmdma = pci_resource_start(pdev, 4);
- if (bmdma != 0) {
- bmdma += 8 * port_num;
- probe_ent->port[0].bmdma_addr = bmdma;
- if (inb(bmdma + 2) & 0x80)
- probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
+ if (port_mask & ATA_PORT_PRIMARY) {
+ probe_ent->irq = 14;
+ probe_ent->port[port_num].cmd_addr = ATA_PRIMARY_CMD;
+ probe_ent->port[port_num].altstatus_addr =
+ probe_ent->port[port_num].ctl_addr = ATA_PRIMARY_CTL;
+ if (bmdma) {
+ probe_ent->port[0].bmdma_addr = bmdma;
+ if (inb(bmdma + 2) & 0x80)
+ probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
+ }
+ ata_std_ports(&probe_ent->port[port_num]);
+ port_num ++;
+ }
+ if (port_mask & ATA_PORT_SECONDARY) {
+ if (port_num == 1)
+ probe_ent->irq2 = 15;
+ else {
+ /* Secondary only. IRQ 15 only and "first" port is port 1 */
+ probe_ent->irq = 15;
+ probe_ent->hard_port_no = 1;
+ }
+ probe_ent->port[port_num].cmd_addr = ATA_SECONDARY_CMD;
+ probe_ent->port[port_num].altstatus_addr =
+ probe_ent->port[port_num].ctl_addr = ATA_SECONDARY_CTL;
+ port_num ++;
+ if (bmdma) {
+ probe_ent->port[port_num].bmdma_addr = bmdma + 8;
+ if (inb(bmdma + 10) & 0x80)
+ probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
+ }
+ ata_std_ports(&probe_ent->port[port_num]);
+ port_num ++;
}
- ata_std_ports(&probe_ent->port[0]);
-
return probe_ent;
}
@@ -950,6 +960,10 @@ static struct ata_probe_ent *ata_pci_ini
* regions, sets the dma mask, enables bus master mode, and calls
* ata_device_add()
*
+ * ASSUMPTION:
+ * Nobody makes a single channel controller that appears solely as
+ * the secondary legacy port on PCI.
+ *
* LOCKING:
* Inherited from PCI layer (may sleep).
*
@@ -960,7 +974,7 @@ static struct ata_probe_ent *ata_pci_ini
int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
unsigned int n_ports)
{
- struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL;
+ struct ata_probe_ent *probe_ent = NULL;
struct ata_port_info *port[2];
u8 tmp8, mask;
unsigned int legacy_mode = 0;
@@ -1009,35 +1023,34 @@ int ata_pci_init_one (struct pci_dev *pd
goto err_out;
}
- /* FIXME: Should use platform specific mappers for legacy port ranges */
if (legacy_mode) {
- if (!request_region(0x1f0, 8, "libata")) {
+ if (!request_region(ATA_PRIMARY_CMD, 8, "libata")) {
struct resource *conflict, res;
- res.start = 0x1f0;
- res.end = 0x1f0 + 8 - 1;
+ res.start = ATA_PRIMARY_CMD;
+ res.end = ATA_PRIMARY_CMD + 8 - 1;
conflict = ____request_resource(&ioport_resource, &res);
if (!strcmp(conflict->name, "libata"))
- legacy_mode |= (1 << 0);
+ legacy_mode |= ATA_PORT_PRIMARY;
else {
disable_dev_on_err = 0;
- printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n");
+ printk(KERN_WARNING "ata: 0x%0X IDE port busy\n", ATA_PRIMARY_CMD);
}
} else
- legacy_mode |= (1 << 0);
+ legacy_mode |= ATA_PORT_PRIMARY;
- if (!request_region(0x170, 8, "libata")) {
+ if (!request_region(ATA_SECONDARY_CMD, 8, "libata")) {
struct resource *conflict, res;
- res.start = 0x170;
- res.end = 0x170 + 8 - 1;
+ res.start = ATA_SECONDARY_CMD;
+ res.end = ATA_SECONDARY_CMD + 8 - 1;
conflict = ____request_resource(&ioport_resource, &res);
if (!strcmp(conflict->name, "libata"))
- legacy_mode |= (1 << 1);
+ legacy_mode |= ATA_PORT_SECONDARY;
else {
disable_dev_on_err = 0;
- printk(KERN_WARNING "ata: 0x170 IDE port busy\n");
+ printk(KERN_WARNING "ata: 0x%X IDE port busy\n", ATA_SECONDARY_CMD);
}
} else
- legacy_mode |= (1 << 1);
+ legacy_mode |= ATA_PORT_SECONDARY;
}
/* we have legacy mode, but all ports are unavailable */
@@ -1055,17 +1068,14 @@ int ata_pci_init_one (struct pci_dev *pd
goto err_out_regions;
if (legacy_mode) {
- if (legacy_mode & (1 << 0))
- probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0);
- if (legacy_mode & (1 << 1))
- probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1);
+ probe_ent = ata_pci_init_legacy_port(pdev, port, legacy_mode);
} else {
if (n_ports == 2)
probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
else
probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY);
}
- if (!probe_ent && !probe_ent2) {
+ if (!probe_ent) {
rc = -ENOMEM;
goto err_out_regions;
}
@@ -1073,35 +1083,17 @@ int ata_pci_init_one (struct pci_dev *pd
pci_set_master(pdev);
/* FIXME: check ata_device_add return */
- if (legacy_mode) {
- struct device *dev = &pdev->dev;
- struct ata_host_set *host_set = NULL;
-
- if (legacy_mode & (1 << 0)) {
- ata_device_add(probe_ent);
- host_set = dev_get_drvdata(dev);
- }
-
- if (legacy_mode & (1 << 1)) {
- ata_device_add(probe_ent2);
- if (host_set) {
- host_set->next = dev_get_drvdata(dev);
- dev_set_drvdata(dev, host_set);
- }
- }
- } else
- ata_device_add(probe_ent);
+ ata_device_add(probe_ent);
kfree(probe_ent);
- kfree(probe_ent2);
return 0;
err_out_regions:
- if (legacy_mode & (1 << 0))
- release_region(0x1f0, 8);
- if (legacy_mode & (1 << 1))
- release_region(0x170, 8);
+ if (legacy_mode & ATA_PORT_PRIMARY)
+ release_region(ATA_PRIMARY_CMD, 8);
+ if (legacy_mode & ATA_PORT_SECONDARY)
+ release_region(ATA_SECONDARY_CMD, 8);
pci_release_regions(pdev);
err_out:
if (disable_dev_on_err)
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 96fc7a5..a0cc1e5 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -3052,8 +3052,8 @@ static void ata_dev_xfermask(struct ata_
struct ata_port *ap = dev->ap;
struct ata_host_set *hs = ap->host_set;
unsigned long xfer_mask;
- int i;
+ /* Controller modes available */
xfer_mask = ata_pack_xfermask(ap->pio_mask,
ap->mwdma_mask, ap->udma_mask);
@@ -3063,30 +3063,21 @@ static void ata_dev_xfermask(struct ata_
if (ap->cbl == ATA_CBL_PATA40)
xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
- /* FIXME: Use port-wide xfermask for now */
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
- struct ata_device *d = &ap->device[i];
-
- if (ata_dev_absent(d))
- continue;
-
- if (ata_dev_disabled(d)) {
- /* to avoid violating device selection timing */
- xfer_mask &= ata_pack_xfermask(d->pio_mask,
- UINT_MAX, UINT_MAX);
- continue;
- }
-
- xfer_mask &= ata_pack_xfermask(d->pio_mask,
- d->mwdma_mask, d->udma_mask);
- xfer_mask &= ata_id_xfermask(d->id);
- if (ata_dma_blacklisted(d))
- xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
+ if (ata_dev_disabled(dev)) {
+ /* to avoid violating device selection timing */
+ xfer_mask &= ata_pack_xfermask(dev->pio_mask,
+ UINT_MAX, UINT_MAX);
+ goto out;
}
+ xfer_mask &= ata_pack_xfermask(dev->pio_mask,
+ dev->mwdma_mask, dev->udma_mask);
+ xfer_mask &= ata_id_xfermask(dev->id);
- if (ata_dma_blacklisted(dev))
+ if (ata_dma_blacklisted(dev)) {
+ xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
ata_dev_printk(dev, KERN_WARNING,
"device is on DMA blacklist, disabling DMA\n");
+ }
if (hs->flags & ATA_HOST_SIMPLEX) {
if (hs->simplex_claimed)
@@ -3095,7 +3086,7 @@ static void ata_dev_xfermask(struct ata_
if (ap->ops->mode_filter)
xfer_mask = ap->ops->mode_filter(ap, dev, xfer_mask);
-
+out:
ata_unpack_xfermask(xfer_mask, &dev->pio_mask,
&dev->mwdma_mask, &dev->udma_mask);
}
@@ -5251,6 +5242,7 @@ static void ata_port_init(struct ata_por
ap->host_set = host_set;
ap->dev = ent->dev;
ap->port_no = port_no;
+
ap->hard_port_no =
ent->legacy_mode ? ent->hard_port_no : port_no;
ap->pio_mask = ent->pio_mask;
@@ -5386,6 +5378,7 @@ int ata_device_add(const struct ata_prob
host_set->dev = dev;
host_set->n_ports = ent->n_ports;
host_set->irq = ent->irq;
+ host_set->irq2 = ent->irq2;
host_set->mmio_base = ent->mmio_base;
host_set->private_data = ent->private_data;
host_set->ops = ent->port_ops;
@@ -5395,16 +5388,22 @@ int ata_device_add(const struct ata_prob
for (i = 0; i < host_set->n_ports; i++) {
struct ata_port *ap;
unsigned long xfer_mode_mask;
+ int irq_line = ent->irq;
ap = ata_port_add(ent, host_set, i);
if (!ap)
goto err_out;
+ /* Report the secondary IRQ for second channel legacy */
+ if (i == 1 && ent->irq2)
+ irq_line = ent->irq2;
+
host_set->ports[i] = ap;
xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) |
(ap->mwdma_mask << ATA_SHIFT_MWDMA) |
(ap->pio_mask << ATA_SHIFT_PIO);
+ /* FIXME: maybe print both IRQ lines ? */
/* print per-port info to dmesg */
ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%lX "
"ctl 0x%lX bmdma 0x%lX irq %lu\n",
@@ -5420,7 +5419,7 @@ int ata_device_add(const struct ata_prob
ata_eh_freeze_port(ap); /* freeze port before requesting IRQ */
}
- /* obtain irq, that is shared between channels */
+ /* obtain irq, that may be shared between channels */
rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
DRV_NAME, host_set);
if (rc) {
@@ -5429,6 +5428,21 @@ int ata_device_add(const struct ata_prob
goto err_out;
}
+ /* do we have a second IRQ for the other channel, eg legacy mode */
+ if (ent->irq2) {
+ /* We will get weird core code crashes later if this is true
+ so trap it now */
+ BUG_ON(ent->irq == ent->irq2);
+
+ rc = request_irq(ent->irq2, ent->port_ops->irq_handler, ent->irq_flags,
+ DRV_NAME, host_set);
+ if (rc) {
+ dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n",
+ ent->irq2, rc);
+ goto err_out;
+ }
+ }
+
/* perform each probe synchronously */
DPRINTK("probe begin\n");
for (i = 0; i < host_set->n_ports; i++) {
@@ -5592,6 +5606,8 @@ void ata_host_set_remove(struct ata_host
ata_port_detach(host_set->ports[i]);
free_irq(host_set->irq, host_set);
+ if (host_set->irq2)
+ free_irq(host_set->irq2, host_set);
for (i = 0; i < host_set->n_ports; i++) {
struct ata_port *ap = host_set->ports[i];
@@ -5601,10 +5617,11 @@ void ata_host_set_remove(struct ata_host
if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {
struct ata_ioports *ioaddr = &ap->ioaddr;
- if (ioaddr->cmd_addr == 0x1f0)
- release_region(0x1f0, 8);
- else if (ioaddr->cmd_addr == 0x170)
- release_region(0x170, 8);
+ /* FIXME: Add -ac IDE pci mods to remove these special cases */
+ if (ioaddr->cmd_addr == ATA_PRIMARY_CMD)
+ release_region(ATA_PRIMARY_CMD, 8);
+ else if (ioaddr->cmd_addr == ATA_SECONDARY_CMD)
+ release_region(ATA_SECONDARY_CMD, 8);
}
scsi_host_put(ap->host);
@@ -5697,11 +5714,8 @@ void ata_pci_remove_one (struct pci_dev
{
struct device *dev = pci_dev_to_dev(pdev);
struct ata_host_set *host_set = dev_get_drvdata(dev);
- struct ata_host_set *host_set2 = host_set->next;
ata_host_set_remove(host_set);
- if (host_set2)
- ata_host_set_remove(host_set2);
pci_release_regions(pdev);
pci_disable_device(pdev);
@@ -5769,14 +5783,6 @@ int ata_pci_device_suspend(struct pci_de
if (rc)
return rc;
- if (host_set->next) {
- rc = ata_host_set_suspend(host_set->next, mesg);
- if (rc) {
- ata_host_set_resume(host_set);
- return rc;
- }
- }
-
ata_pci_device_do_suspend(pdev, mesg);
return 0;
@@ -5788,9 +5794,6 @@ int ata_pci_device_resume(struct pci_dev
ata_pci_device_do_resume(pdev);
ata_host_set_resume(host_set);
- if (host_set->next)
- ata_host_set_resume(host_set->next);
-
return 0;
}
#endif /* CONFIG_PCI */
diff --git a/include/asm-alpha/libata-portmap.h b/include/asm-alpha/libata-portmap.h
new file mode 100644
index 0000000..75484ef
--- /dev/null
+++ b/include/asm-alpha/libata-portmap.h
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
diff --git a/include/asm-generic/libata-portmap.h b/include/asm-generic/libata-portmap.h
new file mode 100644
index 0000000..9202fd0
--- /dev/null
+++ b/include/asm-generic/libata-portmap.h
@@ -0,0 +1,12 @@
+#ifndef __ASM_GENERIC_LIBATA_PORTMAP_H
+#define __ASM_GENERIC_LIBATA_PORTMAP_H
+
+#define ATA_PRIMARY_CMD 0x1F0
+#define ATA_PRIMARY_CTL 0x3F6
+#define ATA_PRIMARY_IRQ 14
+
+#define ATA_SECONDARY_CMD 0x170
+#define ATA_SECONDARY_CTL 0x376
+#define ATA_SECONDARY_IRQ 15
+
+#endif
diff --git a/include/asm-i386/libata-portmap.h b/include/asm-i386/libata-portmap.h
new file mode 100644
index 0000000..75484ef
--- /dev/null
+++ b/include/asm-i386/libata-portmap.h
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
diff --git a/include/asm-ia64/libata-portmap.h b/include/asm-ia64/libata-portmap.h
new file mode 100644
index 0000000..75484ef
--- /dev/null
+++ b/include/asm-ia64/libata-portmap.h
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
diff --git a/include/asm-powerpc/libata-portmap.h b/include/asm-powerpc/libata-portmap.h
new file mode 100644
index 0000000..75484ef
--- /dev/null
+++ b/include/asm-powerpc/libata-portmap.h
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
diff --git a/include/asm-sparc/libata-portmap.h b/include/asm-sparc/libata-portmap.h
new file mode 100644
index 0000000..75484ef
--- /dev/null
+++ b/include/asm-sparc/libata-portmap.h
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
diff --git a/include/asm-sparc64/libata-portmap.h b/include/asm-sparc64/libata-portmap.h
new file mode 100644
index 0000000..75484ef
--- /dev/null
+++ b/include/asm-sparc64/libata-portmap.h
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
diff --git a/include/asm-x86_64/libata-portmap.h b/include/asm-x86_64/libata-portmap.h
new file mode 100644
index 0000000..75484ef
--- /dev/null
+++ b/include/asm-x86_64/libata-portmap.h
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
diff --git a/include/linux/libata.h b/include/linux/libata.h
index b941670..9a94778 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -36,6 +36,8 @@ #include <linux/ata.h>
#include <linux/workqueue.h>
#include <scsi/scsi_host.h>
+#include <asm/libata-portmap.h>
+
/*
* compile-time options: to be removed as soon as all the drivers are
* converted to the new debugging mechanism
@@ -356,6 +358,7 @@ struct ata_probe_ent {
unsigned int udma_mask;
unsigned int legacy_mode;
unsigned long irq;
+ unsigned long irq2;
unsigned int irq_flags;
unsigned long host_flags;
unsigned long host_set_flags;
@@ -367,6 +370,7 @@ struct ata_host_set {
spinlock_t lock;
struct device *dev;
unsigned long irq;
+ unsigned long irq2;
void __iomem *mmio_base;
unsigned int n_ports;
void *private_data;
@@ -374,7 +378,6 @@ struct ata_host_set {
unsigned long flags;
int simplex_claimed; /* Keep seperate in case we
ever need to do this locked */
- struct ata_host_set *next; /* for legacy mode */
struct ata_port *ports[0];
};
--
1.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 11/11] libata: kill unused hard_port_no and legacy_mode
2006-08-01 20:11 [PATCHSET] libata: improve initialization and legacy handling Tejun Heo
` (8 preceding siblings ...)
2006-08-01 20:11 ` [PATCH 09/11] libata: use dummy port for stolen legacy ports Tejun Heo
@ 2006-08-01 20:11 ` Tejun Heo
2006-08-01 20:11 ` [PATCH 10/11] libata: replace ap->hard_port_no with ap->port_no Tejun Heo
2006-08-01 21:57 ` [PATCHSET] libata: improve initialization and legacy handling Alan Cox
11 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-01 20:11 UTC (permalink / raw)
To: jgarzik, alan; +Cc: Tejun Heo
Kill unused probe_ent/ap->hard_port_no and probe_ent->legacy_mode.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/scsi/libata-core.c | 1 -
include/linux/libata.h | 3 ---
2 files changed, 0 insertions(+), 4 deletions(-)
dbcc858991d3617344dc560ce672238e2d1b62e5
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index fca6c8c..087a845 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5243,7 +5243,6 @@ static void ata_port_init(struct ata_por
ap->dev = ent->dev;
ap->port_no = port_no;
- ap->hard_port_no = port_no;
ap->pio_mask = ent->pio_mask;
ap->mwdma_mask = ent->mwdma_mask;
ap->udma_mask = ent->udma_mask;
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 10c5587..a1c25af 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -352,12 +352,10 @@ struct ata_probe_ent {
struct scsi_host_template *sht;
struct ata_ioports port[ATA_MAX_PORTS];
unsigned int n_ports;
- unsigned int hard_port_no;
unsigned int dummy_port_mask;
unsigned int pio_mask;
unsigned int mwdma_mask;
unsigned int udma_mask;
- unsigned int legacy_mode;
unsigned long irq;
unsigned long irq2;
unsigned int irq_flags;
@@ -509,7 +507,6 @@ struct ata_port {
unsigned int pflags; /* ATA_PFLAG_xxx */
unsigned int id; /* unique id req'd by scsi midlyr */
unsigned int port_no; /* unique port #; from zero */
- unsigned int hard_port_no; /* hardware port #; from zero */
struct ata_prd *prd; /* our SG list */
dma_addr_t prd_dma; /* and its DMA mapping */
--
1.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 09/11] libata: use dummy port for stolen legacy ports
2006-08-01 20:11 [PATCHSET] libata: improve initialization and legacy handling Tejun Heo
` (7 preceding siblings ...)
2006-08-01 20:11 ` [PATCH 07/11] libata: fix several bugs in reworked legacy handling Tejun Heo
@ 2006-08-01 20:11 ` Tejun Heo
2006-08-01 20:11 ` [PATCH 11/11] libata: kill unused hard_port_no and legacy_mode Tejun Heo
` (2 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-01 20:11 UTC (permalink / raw)
To: jgarzik, alan; +Cc: Tejun Heo
Use dummy port for stolen legacy ports. This makes ap->port_no always
equal ap->hard_port_no.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/scsi/libata-bmdma.c | 41 +++++++++++++++++------------------------
drivers/scsi/libata-core.c | 2 --
2 files changed, 17 insertions(+), 26 deletions(-)
9b431bc519065fee6a056356ce2fa8f942d6fd2e
diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c
index d43dc9a..c4cd578 100644
--- a/drivers/scsi/libata-bmdma.c
+++ b/drivers/scsi/libata-bmdma.c
@@ -898,50 +898,43 @@ static struct ata_probe_ent *ata_pci_ini
struct ata_probe_ent *probe_ent;
unsigned long bmdma = pci_resource_start(pdev, 4);
- int port_num = 0;
-
probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
if (!probe_ent)
return NULL;
- probe_ent->legacy_mode = 1;
- probe_ent->hard_port_no = 0;
+ probe_ent->n_ports = 2;
probe_ent->private_data = port[0]->private_data;
if (port_mask & ATA_PORT_PRIMARY) {
probe_ent->irq = 14;
- probe_ent->port[port_num].cmd_addr = ATA_PRIMARY_CMD;
- probe_ent->port[port_num].altstatus_addr =
- probe_ent->port[port_num].ctl_addr = ATA_PRIMARY_CTL;
+ probe_ent->port[0].cmd_addr = ATA_PRIMARY_CMD;
+ probe_ent->port[0].altstatus_addr =
+ probe_ent->port[0].ctl_addr = ATA_PRIMARY_CTL;
if (bmdma) {
probe_ent->port[0].bmdma_addr = bmdma;
if (inb(bmdma + 2) & 0x80)
probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
}
- ata_std_ports(&probe_ent->port[port_num]);
- port_num ++;
- }
+ ata_std_ports(&probe_ent->port[0]);
+ } else
+ probe_ent->dummy_port_mask |= ATA_PORT_PRIMARY;
+
if (port_mask & ATA_PORT_SECONDARY) {
- if (port_num == 1)
+ if (probe_ent->irq)
probe_ent->irq2 = 15;
- else {
- /* Secondary only. IRQ 15 only and "first" port is port 1 */
+ else
probe_ent->irq = 15;
- probe_ent->hard_port_no = 1;
- }
- probe_ent->port[port_num].cmd_addr = ATA_SECONDARY_CMD;
- probe_ent->port[port_num].altstatus_addr =
- probe_ent->port[port_num].ctl_addr = ATA_SECONDARY_CTL;
+ probe_ent->port[1].cmd_addr = ATA_SECONDARY_CMD;
+ probe_ent->port[1].altstatus_addr =
+ probe_ent->port[1].ctl_addr = ATA_SECONDARY_CTL;
if (bmdma) {
- probe_ent->port[port_num].bmdma_addr = bmdma + 8;
+ probe_ent->port[1].bmdma_addr = bmdma + 8;
if (inb(bmdma + 10) & 0x80)
probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
}
- ata_std_ports(&probe_ent->port[port_num]);
- port_num ++;
- }
-
- probe_ent->n_ports = port_num;
+ ata_std_ports(&probe_ent->port[1]);
+ } else
+ probe_ent->dummy_port_mask |= ATA_PORT_SECONDARY;
return probe_ent;
}
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index fffb38a..fca6c8c 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5244,8 +5244,6 @@ static void ata_port_init(struct ata_por
ap->port_no = port_no;
ap->hard_port_no = port_no;
- if (ent->legacy_mode)
- ap->hard_port_no += ent->hard_port_no;
ap->pio_mask = ent->pio_mask;
ap->mwdma_mask = ent->mwdma_mask;
ap->udma_mask = ent->udma_mask;
--
1.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 07/11] libata: fix several bugs in reworked legacy handling
2006-08-01 20:11 [PATCHSET] libata: improve initialization and legacy handling Tejun Heo
` (6 preceding siblings ...)
2006-08-01 20:11 ` [PATCH 08/11] libata: implement dummy port Tejun Heo
@ 2006-08-01 20:11 ` Tejun Heo
2006-08-01 20:11 ` [PATCH 09/11] libata: use dummy port for stolen legacy ports Tejun Heo
` (3 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-01 20:11 UTC (permalink / raw)
To: jgarzik, alan; +Cc: Tejun Heo
This patch fixes the following bugs from reworked legacy handling.
* In ata_pci_init_legacy_port(), probe_num was incorrectly incremented
during initialization of the secondary port and probe_ent->n_ports
was incorrectly fixed to 1.
* Both legacy ports ended up having the same hard_port_no.
* When printing port information, both legacy ports printed the first
irq.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/scsi/libata-bmdma.c | 5 +++--
drivers/scsi/libata-core.c | 14 ++++++++------
2 files changed, 11 insertions(+), 8 deletions(-)
0df39c4bc9c811d9715139411206d3e8f5a32d6b
diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c
index 34343e5..d43dc9a 100644
--- a/drivers/scsi/libata-bmdma.c
+++ b/drivers/scsi/libata-bmdma.c
@@ -905,7 +905,6 @@ static struct ata_probe_ent *ata_pci_ini
return NULL;
probe_ent->legacy_mode = 1;
- probe_ent->n_ports = 1;
probe_ent->hard_port_no = 0;
probe_ent->private_data = port[0]->private_data;
@@ -933,7 +932,6 @@ static struct ata_probe_ent *ata_pci_ini
probe_ent->port[port_num].cmd_addr = ATA_SECONDARY_CMD;
probe_ent->port[port_num].altstatus_addr =
probe_ent->port[port_num].ctl_addr = ATA_SECONDARY_CTL;
- port_num ++;
if (bmdma) {
probe_ent->port[port_num].bmdma_addr = bmdma + 8;
if (inb(bmdma + 10) & 0x80)
@@ -942,6 +940,9 @@ static struct ata_probe_ent *ata_pci_ini
ata_std_ports(&probe_ent->port[port_num]);
port_num ++;
}
+
+ probe_ent->n_ports = port_num;
+
return probe_ent;
}
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index a0cc1e5..fe23738 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5243,8 +5243,9 @@ static void ata_port_init(struct ata_por
ap->dev = ent->dev;
ap->port_no = port_no;
- ap->hard_port_no =
- ent->legacy_mode ? ent->hard_port_no : port_no;
+ ap->hard_port_no = port_no;
+ if (ent->legacy_mode)
+ ap->hard_port_no += ent->hard_port_no;
ap->pio_mask = ent->pio_mask;
ap->mwdma_mask = ent->mwdma_mask;
ap->udma_mask = ent->udma_mask;
@@ -5403,16 +5404,15 @@ int ata_device_add(const struct ata_prob
(ap->mwdma_mask << ATA_SHIFT_MWDMA) |
(ap->pio_mask << ATA_SHIFT_PIO);
- /* FIXME: maybe print both IRQ lines ? */
/* print per-port info to dmesg */
ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%lX "
- "ctl 0x%lX bmdma 0x%lX irq %lu\n",
+ "ctl 0x%lX bmdma 0x%lX irq %d\n",
ap->flags & ATA_FLAG_SATA ? 'S' : 'P',
ata_mode_string(xfer_mode_mask),
ap->ioaddr.cmd_addr,
ap->ioaddr.ctl_addr,
ap->ioaddr.bmdma_addr,
- ent->irq);
+ irq_line);
ata_chk_status(ap);
host_set->ops->irq_clear(ap);
@@ -5439,7 +5439,7 @@ int ata_device_add(const struct ata_prob
if (rc) {
dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n",
ent->irq2, rc);
- goto err_out;
+ goto err_out_free_irq;
}
}
@@ -5516,6 +5516,8 @@ int ata_device_add(const struct ata_prob
VPRINTK("EXIT, returning %u\n", ent->n_ports);
return ent->n_ports; /* success */
+err_out_free_irq:
+ free_irq(ent->irq, host_set);
err_out:
for (i = 0; i < host_set->n_ports; i++) {
struct ata_port *ap = host_set->ports[i];
--
1.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 10/11] libata: replace ap->hard_port_no with ap->port_no
2006-08-01 20:11 [PATCHSET] libata: improve initialization and legacy handling Tejun Heo
` (9 preceding siblings ...)
2006-08-01 20:11 ` [PATCH 11/11] libata: kill unused hard_port_no and legacy_mode Tejun Heo
@ 2006-08-01 20:11 ` Tejun Heo
2006-08-01 21:57 ` [PATCHSET] libata: improve initialization and legacy handling Alan Cox
11 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-01 20:11 UTC (permalink / raw)
To: jgarzik, alan; +Cc: Tejun Heo
Replace ap->hard_port_no with ap->port_no.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/scsi/ata_piix.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
1ca7e026372e14ae0b7aa47dea46cf4e55649fc1
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index dfdf4a7..99ed16c 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -487,7 +487,7 @@ static void piix_pata_cbl_detect(struct
goto cbl40;
/* check BIOS cable detect results */
- mask = ap->hard_port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC;
+ mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC;
pci_read_config_byte(pdev, PIIX_IOCFG, &tmp);
if ((tmp & mask) == 0)
goto cbl40;
@@ -513,7 +513,7 @@ static int piix_pata_prereset(struct ata
{
struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
- if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->hard_port_no])) {
+ if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no])) {
ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n");
ap->eh_context.i.action &= ~ATA_EH_RESET_MASK;
return 0;
@@ -550,7 +550,7 @@ static int piix_sata_prereset(struct ata
struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
struct piix_host_priv *hpriv = ap->host_set->private_data;
const unsigned int *map = hpriv->map;
- int base = 2 * ap->hard_port_no;
+ int base = 2 * ap->port_no;
unsigned int present = 0;
int port, i;
u16 pcs;
@@ -601,7 +601,7 @@ static void piix_set_piomode (struct ata
unsigned int pio = adev->pio_mode - XFER_PIO_0;
struct pci_dev *dev = to_pci_dev(ap->host_set->dev);
unsigned int is_slave = (adev->devno != 0);
- unsigned int master_port= ap->hard_port_no ? 0x42 : 0x40;
+ unsigned int master_port= ap->port_no ? 0x42 : 0x40;
unsigned int slave_port = 0x44;
u16 master_data;
u8 slave_data;
@@ -619,10 +619,10 @@ static void piix_set_piomode (struct ata
/* enable PPE, IE and TIME */
master_data |= 0x0070;
pci_read_config_byte(dev, slave_port, &slave_data);
- slave_data &= (ap->hard_port_no ? 0x0f : 0xf0);
+ slave_data &= (ap->port_no ? 0x0f : 0xf0);
slave_data |=
(timings[pio][0] << 2) |
- (timings[pio][1] << (ap->hard_port_no ? 4 : 0));
+ (timings[pio][1] << (ap->port_no ? 4 : 0));
} else {
master_data &= 0xccf8;
/* enable PPE, IE and TIME */
@@ -652,9 +652,9 @@ static void piix_set_dmamode (struct ata
{
unsigned int udma = adev->dma_mode; /* FIXME: MWDMA too */
struct pci_dev *dev = to_pci_dev(ap->host_set->dev);
- u8 maslave = ap->hard_port_no ? 0x42 : 0x40;
+ u8 maslave = ap->port_no ? 0x42 : 0x40;
u8 speed = udma;
- unsigned int drive_dn = (ap->hard_port_no ? 2 : 0) + adev->devno;
+ unsigned int drive_dn = (ap->port_no ? 2 : 0) + adev->devno;
int a_speed = 3 << (drive_dn * 4);
int u_flag = 1 << drive_dn;
int v_flag = 0x01 << drive_dn;
--
1.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCHSET] libata: improve initialization and legacy handling
2006-08-01 20:11 [PATCHSET] libata: improve initialization and legacy handling Tejun Heo
` (10 preceding siblings ...)
2006-08-01 20:11 ` [PATCH 10/11] libata: replace ap->hard_port_no with ap->port_no Tejun Heo
@ 2006-08-01 21:57 ` Alan Cox
11 siblings, 0 replies; 13+ messages in thread
From: Alan Cox @ 2006-08-01 21:57 UTC (permalink / raw)
To: Tejun Heo; +Cc: jgarzik, akpm, davej, linux-ide
Ar Mer, 2006-08-02 am 05:11 +0900, ysgrifennodd Tejun Heo:
> Hello, all.
>
> This patchset contains patches from Jeff Garzik, Alan Cox, Dave Jones
> and me to fix/clean up initializaton and legacy handling. This
> patchset contains the following patches.
Acked-by: Alan Cox <alan@redhat.com)
for all 11 patches
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2006-08-01 21:39 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-01 20:11 [PATCHSET] libata: improve initialization and legacy handling Tejun Heo
2006-08-01 20:11 ` [PATCH 05/11] libata: fix ata_device_add() error path Tejun Heo
2006-08-01 20:11 ` [PATCH 04/11] [libata] Kill 'count' var in ata_device_add() Tejun Heo
2006-08-01 20:11 ` [PATCH 02/11] [libata] some function renaming Tejun Heo
2006-08-01 20:11 ` [PATCH 01/11] ata_piix: fix host_set private_data intialization Tejun Heo
2006-08-01 20:11 ` [PATCH 03/11] [libata] manually inline ata_host_remove() Tejun Heo
2006-08-01 20:11 ` [PATCH 06/11] libata: rework legacy handling to remove much of the cruft Tejun Heo
2006-08-01 20:11 ` [PATCH 08/11] libata: implement dummy port Tejun Heo
2006-08-01 20:11 ` [PATCH 07/11] libata: fix several bugs in reworked legacy handling Tejun Heo
2006-08-01 20:11 ` [PATCH 09/11] libata: use dummy port for stolen legacy ports Tejun Heo
2006-08-01 20:11 ` [PATCH 11/11] libata: kill unused hard_port_no and legacy_mode Tejun Heo
2006-08-01 20:11 ` [PATCH 10/11] libata: replace ap->hard_port_no with ap->port_no Tejun Heo
2006-08-01 21:57 ` [PATCHSET] libata: improve initialization and legacy handling Alan Cox
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).