Commit b2665fe6 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'ata-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux

Pull ata updates from Damien Le Moal:

 - Convert the bindings for the imx-pata and ahci-da850 drivers to DT
   schemas (from Animesh)

 - Correct the code to handle HAS_IOPORT dependencies and conditionally
   compile drivers as needed (from Niklas)

 - Correct the legacy_exit() function in the pata_legacy driver to
   properly handle cleanups on driver exit (from Sergey)

 - Small code simplification removing the ata_exec_internal_sg()
   function and folding it into its only caller (from me)

* tag 'ata-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux:
  ata: pata_legacy: make legacy_exit() work again
  ata: libata-core: Remove ata_exec_internal_sg()
  ata: add HAS_IOPORT dependencies
  dt-bindings: ata: ahci-da850: Convert to dtschema
  dt-bindings: ata: imx-pata: Convert to dtschema
parents b47c1823 d4a89339
Device tree binding for the TI DA850 AHCI SATA Controller
---------------------------------------------------------
Required properties:
- compatible: must be "ti,da850-ahci"
- reg: physical base addresses and sizes of the two register regions
used by the controller: the register map as defined by the
AHCI 1.1 standard and the Power Down Control Register (PWRDN)
for enabling/disabling the SATA clock receiver
- interrupts: interrupt specifier (refer to the interrupt binding)
Example:
sata: sata@218000 {
compatible = "ti,da850-ahci";
reg = <0x218000 0x2000>, <0x22c018 0x4>;
interrupts = <67>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/ata/fsl,imx-pata.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX PATA Controller
maintainers:
- Animesh Agarwal <animeshagarwal28@gmail.com>
properties:
compatible:
oneOf:
- items:
- enum:
- fsl,imx31-pata
- fsl,imx51-pata
- const: fsl,imx27-pata
- const: fsl,imx27-pata
reg:
maxItems: 1
interrupts:
items:
- description: PATA Controller interrupts
clocks:
items:
- description: PATA Controller clocks
additionalProperties: false
examples:
- |
pata: pata@83fe0000 {
compatible = "fsl,imx51-pata", "fsl,imx27-pata";
reg = <0x83fe0000 0x4000>;
interrupts = <70>;
clocks = <&clks 161>;
};
* Freescale i.MX PATA Controller
Required properties:
- compatible: "fsl,imx27-pata"
- reg: Address range of the PATA Controller
- interrupts: The interrupt of the PATA Controller
- clocks: the clocks for the PATA Controller
Example:
pata: pata@83fe0000 {
compatible = "fsl,imx51-pata", "fsl,imx27-pata";
reg = <0x83fe0000 0x4000>;
interrupts = <70>;
clocks = <&clks 161>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/ata/ti,da850-ahci.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TI DA850 AHCI SATA Controller
maintainers:
- Animesh Agarwal <animeshagarwal28@gmail.com>
properties:
compatible:
const: ti,da850-ahci
reg:
items:
- description: Address and size of the register map as defined by the AHCI 1.1 standard.
- description:
Address and size of Power Down Control Register (PWRDN) for enabling/disabling the SATA clock
receiver.
interrupts:
maxItems: 1
required:
- compatible
- reg
- interrupts
additionalProperties: false
examples:
- |
sata@218000 {
compatible = "ti,da850-ahci";
reg = <0x218000 0x2000>, <0x22c018 0x4>;
interrupts = <67>;
};
...@@ -556,7 +556,7 @@ comment "PATA SFF controllers with BMDMA" ...@@ -556,7 +556,7 @@ comment "PATA SFF controllers with BMDMA"
config PATA_ALI config PATA_ALI
tristate "ALi PATA support" tristate "ALi PATA support"
depends on PCI depends on PCI && HAS_IOPORT
select PATA_TIMINGS select PATA_TIMINGS
help help
This option enables support for the ALi ATA interfaces This option enables support for the ALi ATA interfaces
...@@ -566,7 +566,7 @@ config PATA_ALI ...@@ -566,7 +566,7 @@ config PATA_ALI
config PATA_AMD config PATA_AMD
tristate "AMD/NVidia PATA support" tristate "AMD/NVidia PATA support"
depends on PCI depends on PCI && HAS_IOPORT
select PATA_TIMINGS select PATA_TIMINGS
help help
This option enables support for the AMD and NVidia PATA This option enables support for the AMD and NVidia PATA
...@@ -584,7 +584,7 @@ config PATA_ARASAN_CF ...@@ -584,7 +584,7 @@ config PATA_ARASAN_CF
config PATA_ARTOP config PATA_ARTOP
tristate "ARTOP 6210/6260 PATA support" tristate "ARTOP 6210/6260 PATA support"
depends on PCI depends on PCI && HAS_IOPORT
help help
This option enables support for ARTOP PATA controllers. This option enables support for ARTOP PATA controllers.
...@@ -611,7 +611,7 @@ config PATA_ATP867X ...@@ -611,7 +611,7 @@ config PATA_ATP867X
config PATA_CMD64X config PATA_CMD64X
tristate "CMD64x PATA support" tristate "CMD64x PATA support"
depends on PCI depends on PCI && HAS_IOPORT
select PATA_TIMINGS select PATA_TIMINGS
help help
This option enables support for the CMD64x series chips This option enables support for the CMD64x series chips
...@@ -658,7 +658,7 @@ config PATA_CS5536 ...@@ -658,7 +658,7 @@ config PATA_CS5536
config PATA_CYPRESS config PATA_CYPRESS
tristate "Cypress CY82C693 PATA support (Very Experimental)" tristate "Cypress CY82C693 PATA support (Very Experimental)"
depends on PCI depends on PCI && HAS_IOPORT
select PATA_TIMINGS select PATA_TIMINGS
help help
This option enables support for the Cypress/Contaq CY82C693 This option enables support for the Cypress/Contaq CY82C693
...@@ -706,7 +706,7 @@ config PATA_HPT366 ...@@ -706,7 +706,7 @@ config PATA_HPT366
config PATA_HPT37X config PATA_HPT37X
tristate "HPT 370/370A/371/372/374/302 PATA support" tristate "HPT 370/370A/371/372/374/302 PATA support"
depends on PCI depends on PCI && HAS_IOPORT
help help
This option enables support for the majority of the later HPT This option enables support for the majority of the later HPT
PATA controllers via the new ATA layer. PATA controllers via the new ATA layer.
...@@ -715,7 +715,7 @@ config PATA_HPT37X ...@@ -715,7 +715,7 @@ config PATA_HPT37X
config PATA_HPT3X2N config PATA_HPT3X2N
tristate "HPT 371N/372N/302N PATA support" tristate "HPT 371N/372N/302N PATA support"
depends on PCI depends on PCI && HAS_IOPORT
help help
This option enables support for the N variant HPT PATA This option enables support for the N variant HPT PATA
controllers via the new ATA layer. controllers via the new ATA layer.
...@@ -818,7 +818,7 @@ config PATA_MPC52xx ...@@ -818,7 +818,7 @@ config PATA_MPC52xx
config PATA_NETCELL config PATA_NETCELL
tristate "NETCELL Revolution RAID support" tristate "NETCELL Revolution RAID support"
depends on PCI depends on PCI && HAS_IOPORT
help help
This option enables support for the Netcell Revolution RAID This option enables support for the Netcell Revolution RAID
PATA controller. PATA controller.
...@@ -854,7 +854,7 @@ config PATA_OLDPIIX ...@@ -854,7 +854,7 @@ config PATA_OLDPIIX
config PATA_OPTIDMA config PATA_OPTIDMA
tristate "OPTI FireStar PATA support (Very Experimental)" tristate "OPTI FireStar PATA support (Very Experimental)"
depends on PCI depends on PCI && HAS_IOPORT
help help
This option enables DMA/PIO support for the later OPTi This option enables DMA/PIO support for the later OPTi
controllers found on some old motherboards and in some controllers found on some old motherboards and in some
...@@ -864,7 +864,7 @@ config PATA_OPTIDMA ...@@ -864,7 +864,7 @@ config PATA_OPTIDMA
config PATA_PDC2027X config PATA_PDC2027X
tristate "Promise PATA 2027x support" tristate "Promise PATA 2027x support"
depends on PCI depends on PCI && HAS_IOPORT
help help
This option enables support for Promise PATA pdc20268 to pdc20277 host adapters. This option enables support for Promise PATA pdc20268 to pdc20277 host adapters.
...@@ -872,7 +872,7 @@ config PATA_PDC2027X ...@@ -872,7 +872,7 @@ config PATA_PDC2027X
config PATA_PDC_OLD config PATA_PDC_OLD
tristate "Older Promise PATA controller support" tristate "Older Promise PATA controller support"
depends on PCI depends on PCI && HAS_IOPORT
help help
This option enables support for the Promise 20246, 20262, 20263, This option enables support for the Promise 20246, 20262, 20263,
20265 and 20267 adapters. 20265 and 20267 adapters.
...@@ -900,7 +900,7 @@ config PATA_RDC ...@@ -900,7 +900,7 @@ config PATA_RDC
config PATA_SC1200 config PATA_SC1200
tristate "SC1200 PATA support" tristate "SC1200 PATA support"
depends on PCI && (X86_32 || COMPILE_TEST) depends on PCI && (X86_32 || COMPILE_TEST) && HAS_IOPORT
help help
This option enables support for the NatSemi/AMD SC1200 SoC This option enables support for the NatSemi/AMD SC1200 SoC
companion chip used with the Geode processor family. companion chip used with the Geode processor family.
...@@ -918,7 +918,7 @@ config PATA_SCH ...@@ -918,7 +918,7 @@ config PATA_SCH
config PATA_SERVERWORKS config PATA_SERVERWORKS
tristate "SERVERWORKS OSB4/CSB5/CSB6/HT1000 PATA support" tristate "SERVERWORKS OSB4/CSB5/CSB6/HT1000 PATA support"
depends on PCI depends on PCI && HAS_IOPORT
help help
This option enables support for the Serverworks OSB4/CSB5/CSB6 and This option enables support for the Serverworks OSB4/CSB5/CSB6 and
HT1000 PATA controllers, via the new ATA layer. HT1000 PATA controllers, via the new ATA layer.
...@@ -1182,7 +1182,7 @@ config ATA_GENERIC ...@@ -1182,7 +1182,7 @@ config ATA_GENERIC
config PATA_LEGACY config PATA_LEGACY
tristate "Legacy ISA PATA support (Experimental)" tristate "Legacy ISA PATA support (Experimental)"
depends on (ISA || PCI) depends on (ISA || PCI) && HAS_IOPORT
select PATA_TIMINGS select PATA_TIMINGS
help help
This option enables support for ISA/VLB/PCI bus legacy PATA This option enables support for ISA/VLB/PCI bus legacy PATA
......
...@@ -1480,19 +1480,19 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc) ...@@ -1480,19 +1480,19 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
} }
/** /**
* ata_exec_internal_sg - execute libata internal command * ata_exec_internal - execute libata internal command
* @dev: Device to which the command is sent * @dev: Device to which the command is sent
* @tf: Taskfile registers for the command and the result * @tf: Taskfile registers for the command and the result
* @cdb: CDB for packet command * @cdb: CDB for packet command
* @dma_dir: Data transfer direction of the command * @dma_dir: Data transfer direction of the command
* @sgl: sg list for the data buffer of the command * @buf: Data buffer of the command
* @n_elem: Number of sg entries * @buflen: Length of data buffer
* @timeout: Timeout in msecs (0 for default) * @timeout: Timeout in msecs (0 for default)
* *
* Executes libata internal command with timeout. @tf contains * Executes libata internal command with timeout. @tf contains
* command on entry and result on return. Timeout and error * the command on entry and the result on return. Timeout and error
* conditions are reported via return value. No recovery action * conditions are reported via the return value. No recovery action
* is taken after a command times out. It's caller's duty to * is taken after a command times out. It is the caller's duty to
* clean up after timeout. * clean up after timeout.
* *
* LOCKING: * LOCKING:
...@@ -1501,34 +1501,38 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc) ...@@ -1501,34 +1501,38 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
* RETURNS: * RETURNS:
* Zero on success, AC_ERR_* mask on failure * Zero on success, AC_ERR_* mask on failure
*/ */
static unsigned ata_exec_internal_sg(struct ata_device *dev, unsigned int ata_exec_internal(struct ata_device *dev, struct ata_taskfile *tf,
struct ata_taskfile *tf, const u8 *cdb, const u8 *cdb, enum dma_data_direction dma_dir,
int dma_dir, struct scatterlist *sgl, void *buf, unsigned int buflen,
unsigned int n_elem, unsigned int timeout) unsigned int timeout)
{ {
struct ata_link *link = dev->link; struct ata_link *link = dev->link;
struct ata_port *ap = link->ap; struct ata_port *ap = link->ap;
u8 command = tf->command; u8 command = tf->command;
int auto_timeout = 0;
struct ata_queued_cmd *qc; struct ata_queued_cmd *qc;
struct scatterlist sgl;
unsigned int preempted_tag; unsigned int preempted_tag;
u32 preempted_sactive; u32 preempted_sactive;
u64 preempted_qc_active; u64 preempted_qc_active;
int preempted_nr_active_links; int preempted_nr_active_links;
bool auto_timeout = false;
DECLARE_COMPLETION_ONSTACK(wait); DECLARE_COMPLETION_ONSTACK(wait);
unsigned long flags; unsigned long flags;
unsigned int err_mask; unsigned int err_mask;
int rc; int rc;
if (WARN_ON(dma_dir != DMA_NONE && !buf))
return AC_ERR_INVALID;
spin_lock_irqsave(ap->lock, flags); spin_lock_irqsave(ap->lock, flags);
/* no internal command while frozen */ /* No internal command while frozen */
if (ata_port_is_frozen(ap)) { if (ata_port_is_frozen(ap)) {
spin_unlock_irqrestore(ap->lock, flags); spin_unlock_irqrestore(ap->lock, flags);
return AC_ERR_SYSTEM; return AC_ERR_SYSTEM;
} }
/* initialize internal qc */ /* Initialize internal qc */
qc = __ata_qc_from_tag(ap, ATA_TAG_INTERNAL); qc = __ata_qc_from_tag(ap, ATA_TAG_INTERNAL);
qc->tag = ATA_TAG_INTERNAL; qc->tag = ATA_TAG_INTERNAL;
...@@ -1547,12 +1551,12 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev, ...@@ -1547,12 +1551,12 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev,
ap->qc_active = 0; ap->qc_active = 0;
ap->nr_active_links = 0; ap->nr_active_links = 0;
/* prepare & issue qc */ /* Prepare and issue qc */
qc->tf = *tf; qc->tf = *tf;
if (cdb) if (cdb)
memcpy(qc->cdb, cdb, ATAPI_CDB_LEN); memcpy(qc->cdb, cdb, ATAPI_CDB_LEN);
/* some SATA bridges need us to indicate data xfer direction */ /* Some SATA bridges need us to indicate data xfer direction */
if (tf->protocol == ATAPI_PROT_DMA && (dev->flags & ATA_DFLAG_DMADIR) && if (tf->protocol == ATAPI_PROT_DMA && (dev->flags & ATA_DFLAG_DMADIR) &&
dma_dir == DMA_FROM_DEVICE) dma_dir == DMA_FROM_DEVICE)
qc->tf.feature |= ATAPI_DMADIR; qc->tf.feature |= ATAPI_DMADIR;
...@@ -1560,13 +1564,8 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev, ...@@ -1560,13 +1564,8 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev,
qc->flags |= ATA_QCFLAG_RESULT_TF; qc->flags |= ATA_QCFLAG_RESULT_TF;
qc->dma_dir = dma_dir; qc->dma_dir = dma_dir;
if (dma_dir != DMA_NONE) { if (dma_dir != DMA_NONE) {
unsigned int i, buflen = 0; sg_init_one(&sgl, buf, buflen);
struct scatterlist *sg; ata_sg_init(qc, &sgl, 1);
for_each_sg(sgl, sg, n_elem, i)
buflen += sg->length;
ata_sg_init(qc, sgl, n_elem);
qc->nbytes = buflen; qc->nbytes = buflen;
} }
...@@ -1578,11 +1577,11 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev, ...@@ -1578,11 +1577,11 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev,
spin_unlock_irqrestore(ap->lock, flags); spin_unlock_irqrestore(ap->lock, flags);
if (!timeout) { if (!timeout) {
if (ata_probe_timeout) if (ata_probe_timeout) {
timeout = ata_probe_timeout * 1000; timeout = ata_probe_timeout * 1000;
else { } else {
timeout = ata_internal_cmd_timeout(dev, command); timeout = ata_internal_cmd_timeout(dev, command);
auto_timeout = 1; auto_timeout = true;
} }
} }
...@@ -1595,30 +1594,25 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev, ...@@ -1595,30 +1594,25 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev,
ata_sff_flush_pio_task(ap); ata_sff_flush_pio_task(ap);
if (!rc) { if (!rc) {
spin_lock_irqsave(ap->lock, flags); /*
* We are racing with irq here. If we lose, the following test
/* We're racing with irq here. If we lose, the * prevents us from completing the qc twice. If we win, the port
* following test prevents us from completing the qc * is frozen and will be cleaned up by ->post_internal_cmd().
* twice. If we win, the port is frozen and will be
* cleaned up by ->post_internal_cmd().
*/ */
spin_lock_irqsave(ap->lock, flags);
if (qc->flags & ATA_QCFLAG_ACTIVE) { if (qc->flags & ATA_QCFLAG_ACTIVE) {
qc->err_mask |= AC_ERR_TIMEOUT; qc->err_mask |= AC_ERR_TIMEOUT;
ata_port_freeze(ap); ata_port_freeze(ap);
ata_dev_warn(dev, "qc timeout after %u msecs (cmd 0x%x)\n", ata_dev_warn(dev, "qc timeout after %u msecs (cmd 0x%x)\n",
timeout, command); timeout, command);
} }
spin_unlock_irqrestore(ap->lock, flags); spin_unlock_irqrestore(ap->lock, flags);
} }
/* do post_internal_cmd */
if (ap->ops->post_internal_cmd) if (ap->ops->post_internal_cmd)
ap->ops->post_internal_cmd(qc); ap->ops->post_internal_cmd(qc);
/* perform minimal error analysis */ /* Perform minimal error analysis */
if (qc->flags & ATA_QCFLAG_EH) { if (qc->flags & ATA_QCFLAG_EH) {
if (qc->result_tf.status & (ATA_ERR | ATA_DF)) if (qc->result_tf.status & (ATA_ERR | ATA_DF))
qc->err_mask |= AC_ERR_DEV; qc->err_mask |= AC_ERR_DEV;
...@@ -1632,7 +1626,7 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev, ...@@ -1632,7 +1626,7 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev,
qc->result_tf.status |= ATA_SENSE; qc->result_tf.status |= ATA_SENSE;
} }
/* finish up */ /* Finish up */
spin_lock_irqsave(ap->lock, flags); spin_lock_irqsave(ap->lock, flags);
*tf = qc->result_tf; *tf = qc->result_tf;
...@@ -1652,44 +1646,6 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev, ...@@ -1652,44 +1646,6 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev,
return err_mask; return err_mask;
} }
/**
* ata_exec_internal - execute libata internal command
* @dev: Device to which the command is sent
* @tf: Taskfile registers for the command and the result
* @cdb: CDB for packet command
* @dma_dir: Data transfer direction of the command
* @buf: Data buffer of the command
* @buflen: Length of data buffer
* @timeout: Timeout in msecs (0 for default)
*
* Wrapper around ata_exec_internal_sg() which takes simple
* buffer instead of sg list.
*
* LOCKING:
* None. Should be called with kernel context, might sleep.
*
* RETURNS:
* Zero on success, AC_ERR_* mask on failure
*/
unsigned ata_exec_internal(struct ata_device *dev,
struct ata_taskfile *tf, const u8 *cdb,
int dma_dir, void *buf, unsigned int buflen,
unsigned int timeout)
{
struct scatterlist *psg = NULL, sg;
unsigned int n_elem = 0;
if (dma_dir != DMA_NONE) {
WARN_ON(!buf);
sg_init_one(&sg, buf, buflen);
psg = &sg;
n_elem++;
}
return ata_exec_internal_sg(dev, tf, cdb, dma_dir, psg, n_elem,
timeout);
}
/** /**
* ata_pio_need_iordy - check if iordy needed * ata_pio_need_iordy - check if iordy needed
* @adev: ATA device * @adev: ATA device
......
...@@ -3032,6 +3032,7 @@ EXPORT_SYMBOL_GPL(ata_bmdma_port_start32); ...@@ -3032,6 +3032,7 @@ EXPORT_SYMBOL_GPL(ata_bmdma_port_start32);
*/ */
int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev) int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev)
{ {
#ifdef CONFIG_HAS_IOPORT
unsigned long bmdma = pci_resource_start(pdev, 4); unsigned long bmdma = pci_resource_start(pdev, 4);
u8 simplex; u8 simplex;
...@@ -3044,6 +3045,9 @@ int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev) ...@@ -3044,6 +3045,9 @@ int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev)
if (simplex & 0x80) if (simplex & 0x80)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return 0; return 0;
#else
return -ENOENT;
#endif /* CONFIG_HAS_IOPORT */
} }
EXPORT_SYMBOL_GPL(ata_pci_bmdma_clear_simplex); EXPORT_SYMBOL_GPL(ata_pci_bmdma_clear_simplex);
......
...@@ -50,9 +50,9 @@ extern int ata_build_rw_tf(struct ata_queued_cmd *qc, u64 block, u32 n_block, ...@@ -50,9 +50,9 @@ extern int ata_build_rw_tf(struct ata_queued_cmd *qc, u64 block, u32 n_block,
unsigned int tf_flags, int dld, int class); unsigned int tf_flags, int dld, int class);
extern u64 ata_tf_read_block(const struct ata_taskfile *tf, extern u64 ata_tf_read_block(const struct ata_taskfile *tf,
struct ata_device *dev); struct ata_device *dev);
extern unsigned ata_exec_internal(struct ata_device *dev, unsigned int ata_exec_internal(struct ata_device *dev, struct ata_taskfile *tf,
struct ata_taskfile *tf, const u8 *cdb, const u8 *cdb, enum dma_data_direction dma_dir,
int dma_dir, void *buf, unsigned int buflen, void *buf, unsigned int buflen,
unsigned int timeout); unsigned int timeout);
extern int ata_wait_ready(struct ata_link *link, unsigned long deadline, extern int ata_wait_ready(struct ata_link *link, unsigned long deadline,
int (*check_ready)(struct ata_link *link)); int (*check_ready)(struct ata_link *link));
......
...@@ -173,8 +173,6 @@ static int legacy_port[NR_HOST] = { 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 }; ...@@ -173,8 +173,6 @@ static int legacy_port[NR_HOST] = { 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 };
static struct legacy_probe probe_list[NR_HOST]; static struct legacy_probe probe_list[NR_HOST];
static struct legacy_data legacy_data[NR_HOST]; static struct legacy_data legacy_data[NR_HOST];
static struct ata_host *legacy_host[NR_HOST]; static struct ata_host *legacy_host[NR_HOST];
static int nr_legacy_host;
/** /**
* legacy_probe_add - Add interface to probe list * legacy_probe_add - Add interface to probe list
...@@ -1276,8 +1274,10 @@ static __exit void legacy_exit(void) ...@@ -1276,8 +1274,10 @@ static __exit void legacy_exit(void)
{ {
int i; int i;
for (i = 0; i < nr_legacy_host; i++) { for (i = 0; i < NR_HOST; i++) {
struct legacy_data *ld = &legacy_data[i]; struct legacy_data *ld = &legacy_data[i];
if (legacy_host[i])
ata_host_detach(legacy_host[i]); ata_host_detach(legacy_host[i]);
platform_device_unregister(ld->platform_dev); platform_device_unregister(ld->platform_dev);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment