ata changes for 6.5-rc1

- Add support for the .remove_new callback to the ata_platform code to
    simplify device removal interface (Uwe).
 
  - Code simplification in ata_dev_revalidate() (Yahu)
 
  - Fix code indentation and coding style in the pata_parport protocol
    modules to avoid warnings from static code analyzers (me)
 
  - Clarify ata_eh_qc_retry() behavior with better comments (Niklas)
 
  - Simplify and improve ata_change_queue_depth() behavior to have a
    consistent behavior between libsas managed devices and libata managed
    devices (e.g. AHCI connected devices) (me).
 
  - Cleanup libata-scsi and libata-eh code to use the ata_ncq_enabled()
    and ata_ncq_supported() helpers instead of open coding flags tests
    (me)
 
  - Cleanup ahci_reset_controller() code (me).
 
  - Change the pata_octeon_cf and sata_svw drivers to use
    of_property_read_reg() to simplify the code (Rob, me).
 
  - Remove unnecessary include files from ahci_octeon driver (me)
 
  - Modify the DesignWare ahci dt bindings to add support for the
    Rockchip RK3588 AHCI (Sebastian).
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQSRPv8tYSvhwAzJdzjdoc3SxdoYdgUCZJourwAKCRDdoc3SxdoY
 dv43AQDzAFY0/0sjvqltGC31wRzzh/vEQFWsYt89Q4csMr4QgAEAkLO1gquH5/Wt
 sxnCLh1WdFqbyNy6xsw+CXrfeREGDgo=
 =IzEr
 -----END PGP SIGNATURE-----

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

Pull ata updates from Damien Le Moal:

 - Add support for the .remove_new callback to the ata_platform code to
   simplify device removal interface (Uwe)

 - Code simplification in ata_dev_revalidate() (Yahu)

 - Fix code indentation and coding style in the pata_parport protocol
   modules to avoid warnings from static code analyzers (me)

 - Clarify ata_eh_qc_retry() behavior with better comments (Niklas)

 - Simplify and improve ata_change_queue_depth() behavior to have a
   consistent behavior between libsas managed devices and libata managed
   devices (e.g. AHCI connected devices) (me)

 - Cleanup libata-scsi and libata-eh code to use the ata_ncq_enabled()
   and ata_ncq_supported() helpers instead of open coding flags tests
   (me)

 - Cleanup ahci_reset_controller() code (me)

 - Change the pata_octeon_cf and sata_svw drivers to use
   of_property_read_reg() to simplify the code (Rob, me)

 - Remove unnecessary include files from ahci_octeon driver (me)

 - Modify the DesignWare ahci dt bindings to add support for the
   Rockchip RK3588 AHCI (Sebastian)

* tag 'ata-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata: (29 commits)
  dt-bindings: phy: rockchip: rk3588 has two reset lines
  dt-bindings: ata: dwc-ahci: add Rockchip RK3588
  dt-bindings: ata: dwc-ahci: add PHY clocks
  ata: ahci_octeon: Remove unnecessary include
  ata: pata_octeon_cf: Add missing header include
  ata: ahci: Cleanup ahci_reset_controller()
  ata: Use of_property_read_reg() to parse "reg"
  ata: libata-scsi: Use ata_ncq_supported in ata_scsi_dev_config()
  ata: libata-eh: Use ata_ncq_enabled() in ata_eh_speed_down()
  ata: libata-sata: Improve ata_change_queue_depth()
  ata: libata-sata: Simplify ata_change_queue_depth()
  ata: libata-eh: Clarify ata_eh_qc_retry() behavior at call site
  ata: pata_parport: Fix on26 module code indentation and style
  ata: pata_parport: Fix on20 module code indentation and style
  ata: pata_parport: Fix ktti module code indentation and style
  ata: pata_parport: Fix kbic module code indentation and style
  ata: pata_parport: Fix friq module code indentation and style
  ata: pata_parport: Fix fit3 module code indentation and style
  ata: pata_parport: Fix fit2 module code indentation and style
  ata: pata_parport: Fix epia module code indentation and style
  ...
This commit is contained in:
Linus Torvalds 2023-06-30 11:48:16 -07:00
commit 1546cd4bfd
48 changed files with 2368 additions and 1978 deletions

View File

@ -0,0 +1,124 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/ata/rockchip,dwc-ahci.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Synopsys DWC AHCI SATA controller for Rockchip devices
maintainers:
- Serge Semin <fancer.lancer@gmail.com>
description:
This document defines device tree bindings for the Synopsys DWC
implementation of the AHCI SATA controller found in Rockchip
devices.
select:
properties:
compatible:
contains:
enum:
- rockchip,rk3568-dwc-ahci
- rockchip,rk3588-dwc-ahci
required:
- compatible
properties:
compatible:
items:
- enum:
- rockchip,rk3568-dwc-ahci
- rockchip,rk3588-dwc-ahci
- const: snps,dwc-ahci
ports-implemented:
const: 1
sata-port@0:
$ref: /schemas/ata/snps,dwc-ahci-common.yaml#/$defs/dwc-ahci-port
properties:
reg:
const: 0
unevaluatedProperties: false
patternProperties:
"^sata-port@[1-9a-e]$": false
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
- ports-implemented
allOf:
- $ref: snps,dwc-ahci-common.yaml#
- if:
properties:
compatible:
contains:
enum:
- rockchip,rk3588-dwc-ahci
then:
properties:
clocks:
maxItems: 5
clock-names:
items:
- const: sata
- const: pmalive
- const: rxoob
- const: ref
- const: asic
- if:
properties:
compatible:
contains:
enum:
- rockchip,rk3568-dwc-ahci
then:
properties:
clocks:
maxItems: 3
clock-names:
items:
- const: sata
- const: pmalive
- const: rxoob
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/rockchip,rk3588-cru.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/ata/ahci.h>
#include <dt-bindings/phy/phy.h>
sata@fe210000 {
compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
reg = <0xfe210000 0x1000>;
clocks = <&cru ACLK_SATA0>, <&cru CLK_PMALIVE0>,
<&cru CLK_RXOOB0>, <&cru CLK_PIPEPHY0_REF>,
<&cru CLK_PIPEPHY0_PIPE_ASIC_G>;
clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH 0>;
ports-implemented = <0x1>;
#address-cells = <1>;
#size-cells = <0>;
sata-port@0 {
reg = <0>;
hba-port-cap = <HBA_PORT_FBSCP>;
phys = <&combphy0_ps PHY_TYPE_SATA>;
phy-names = "sata-phy";
snps,rx-ts-max = <32>;
snps,tx-ts-max = <32>;
};
};
...

View File

@ -31,11 +31,11 @@ properties:
PM-alive clock, RxOOB detection clock, embedded PHYs reference (Rx/Tx)
clock, etc.
minItems: 1
maxItems: 4
maxItems: 6
clock-names:
minItems: 1
maxItems: 4
maxItems: 6
items:
oneOf:
- description: Application APB/AHB/AXI BIU clock
@ -48,6 +48,10 @@ properties:
const: pmalive
- description: RxOOB detection clock
const: rxoob
- description: PHY Transmit Clock
const: asic
- description: PHY Receive Clock
const: rbc
- description: SATA Ports reference clock
const: ref

View File

@ -13,6 +13,15 @@ description:
This document defines device tree bindings for the generic Synopsys DWC
implementation of the AHCI SATA controller.
select:
properties:
compatible:
enum:
- snps,dwc-ahci
- snps,spear-ahci
required:
- compatible
allOf:
- $ref: snps,dwc-ahci-common.yaml#
@ -23,10 +32,6 @@ properties:
const: snps,dwc-ahci
- description: SPEAr1340 AHCI SATA device
const: snps,spear-ahci
- description: Rockhip RK3568 AHCI controller
items:
- const: rockchip,rk3568-dwc-ahci
- const: snps,dwc-ahci
patternProperties:
"^sata-port@[0-9a-e]$":

View File

@ -31,8 +31,14 @@ properties:
- const: pipe
resets:
minItems: 1
maxItems: 2
reset-names:
minItems: 1
items:
- description: exclusive PHY reset line
- const: phy
- const: apb
rockchip,enable-ssc:
type: boolean
@ -78,6 +84,32 @@ required:
- rockchip,pipe-phy-grf
- "#phy-cells"
allOf:
- if:
properties:
compatible:
contains:
const: rockchip,rk3568-naneng-combphy
then:
properties:
resets:
maxItems: 1
reset-names:
maxItems: 1
- if:
properties:
compatible:
contains:
const: rockchip,rk3588-naneng-combphy
then:
properties:
resets:
minItems: 2
reset-names:
minItems: 2
required:
- reset-names
additionalProperties: false
examples:

View File

@ -544,7 +544,7 @@ static int brcm_ahci_probe(struct platform_device *pdev)
return ret;
}
static int brcm_ahci_remove(struct platform_device *pdev)
static void brcm_ahci_remove(struct platform_device *pdev)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
struct ahci_host_priv *hpriv = host->private_data;
@ -552,7 +552,7 @@ static int brcm_ahci_remove(struct platform_device *pdev)
brcm_sata_phys_disable(priv);
return ata_platform_remove_one(pdev);
ata_platform_remove_one(pdev);
}
static void brcm_ahci_shutdown(struct platform_device *pdev)
@ -573,7 +573,7 @@ static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume);
static struct platform_driver brcm_ahci_driver = {
.probe = brcm_ahci_probe,
.remove = brcm_ahci_remove,
.remove_new = brcm_ahci_remove,
.shutdown = brcm_ahci_shutdown,
.driver = {
.name = DRV_NAME,

View File

@ -369,7 +369,7 @@ MODULE_DEVICE_TABLE(of, ceva_ahci_of_match);
static struct platform_driver ceva_ahci_driver = {
.probe = ceva_ahci_probe,
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
.driver = {
.name = DRV_NAME,
.of_match_table = ceva_ahci_of_match,

View File

@ -238,7 +238,7 @@ MODULE_DEVICE_TABLE(of, ahci_da850_of_match);
static struct platform_driver ahci_da850_driver = {
.probe = ahci_da850_probe,
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
.driver = {
.name = DRV_NAME,
.of_match_table = ahci_da850_of_match,

View File

@ -182,7 +182,7 @@ MODULE_DEVICE_TABLE(of, ahci_dm816_of_match);
static struct platform_driver ahci_dm816_driver = {
.probe = ahci_dm816_probe,
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
.driver = {
.name = AHCI_DM816_DRV_NAME,
.of_match_table = ahci_dm816_of_match,

View File

@ -478,7 +478,7 @@ MODULE_DEVICE_TABLE(of, ahci_dwc_of_match);
static struct platform_driver ahci_dwc_driver = {
.probe = ahci_dwc_probe,
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
.shutdown = ahci_platform_shutdown,
.driver = {
.name = DRV_NAME,

View File

@ -1223,7 +1223,7 @@ static SIMPLE_DEV_PM_OPS(ahci_imx_pm_ops, imx_ahci_suspend, imx_ahci_resume);
static struct platform_driver imx_ahci_driver = {
.probe = imx_ahci_probe,
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
.driver = {
.name = DRV_NAME,
.of_match_table = imx_ahci_of_match,

View File

@ -173,7 +173,7 @@ MODULE_DEVICE_TABLE(of, ahci_of_match);
static struct platform_driver mtk_ahci_driver = {
.probe = mtk_ahci_probe,
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
.driver = {
.name = DRV_NAME,
.of_match_table = ahci_of_match,

View File

@ -245,7 +245,7 @@ MODULE_DEVICE_TABLE(of, ahci_mvebu_of_match);
static struct platform_driver ahci_mvebu_driver = {
.probe = ahci_mvebu_probe,
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
.suspend = ahci_mvebu_suspend,
.resume = ahci_mvebu_resume,
.driver = {

View File

@ -16,7 +16,6 @@
#include <linux/of_platform.h>
#include <asm/octeon/octeon.h>
#include <asm/bitfield.h>
#define CVMX_SATA_UCTL_SHIM_CFG 0xE8

View File

@ -96,7 +96,7 @@ MODULE_DEVICE_TABLE(acpi, ahci_acpi_match);
static struct platform_driver ahci_driver = {
.probe = ahci_probe,
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
.shutdown = ahci_platform_shutdown,
.driver = {
.name = DRV_NAME,

View File

@ -359,7 +359,7 @@ static SIMPLE_DEV_PM_OPS(ahci_qoriq_pm_ops, ahci_platform_suspend,
static struct platform_driver ahci_qoriq_driver = {
.probe = ahci_qoriq_probe,
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
.driver = {
.name = DRV_NAME,
.of_match_table = ahci_qoriq_of_match,

View File

@ -187,7 +187,7 @@ MODULE_DEVICE_TABLE(acpi, ahci_acpi_match);
static struct platform_driver ahci_seattle_driver = {
.probe = ahci_seattle_probe,
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
.driver = {
.name = DRV_NAME,
.acpi_match_table = ahci_acpi_match,

View File

@ -239,7 +239,7 @@ static struct platform_driver st_ahci_driver = {
.of_match_table = st_ahci_match,
},
.probe = st_ahci_probe,
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
};
module_platform_driver(st_ahci_driver);

View File

@ -292,7 +292,7 @@ MODULE_DEVICE_TABLE(of, ahci_sunxi_of_match);
static struct platform_driver ahci_sunxi_driver = {
.probe = ahci_sunxi_probe,
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
.driver = {
.name = DRV_NAME,
.of_match_table = ahci_sunxi_of_match,

View File

@ -609,7 +609,7 @@ static int tegra_ahci_probe(struct platform_device *pdev)
static struct platform_driver tegra_ahci_driver = {
.probe = tegra_ahci_probe,
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
.driver = {
.name = DRV_NAME,
.of_match_table = tegra_ahci_of_match,

View File

@ -868,7 +868,7 @@ static int xgene_ahci_probe(struct platform_device *pdev)
static struct platform_driver xgene_ahci_driver = {
.probe = xgene_ahci_probe,
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
.driver = {
.name = DRV_NAME,
.of_match_table = xgene_ahci_of_match,

View File

@ -975,44 +975,43 @@ int ahci_reset_controller(struct ata_host *host)
void __iomem *mmio = hpriv->mmio;
u32 tmp;
/* we must be in AHCI mode, before using anything
* AHCI-specific, such as HOST_RESET.
/*
* We must be in AHCI mode, before using anything AHCI-specific, such
* as HOST_RESET.
*/
ahci_enable_ahci(mmio);
/* global controller reset */
if (!ahci_skip_host_reset) {
tmp = readl(mmio + HOST_CTL);
if ((tmp & HOST_RESET) == 0) {
writel(tmp | HOST_RESET, mmio + HOST_CTL);
readl(mmio + HOST_CTL); /* flush */
}
/* Global controller reset */
if (ahci_skip_host_reset) {
dev_info(host->dev, "Skipping global host reset\n");
return 0;
}
/*
* to perform host reset, OS should set HOST_RESET
* and poll until this bit is read to be "0".
* reset must complete within 1 second, or
* the hardware should be considered fried.
*/
tmp = ata_wait_register(NULL, mmio + HOST_CTL, HOST_RESET,
HOST_RESET, 10, 1000);
tmp = readl(mmio + HOST_CTL);
if (!(tmp & HOST_RESET)) {
writel(tmp | HOST_RESET, mmio + HOST_CTL);
readl(mmio + HOST_CTL); /* flush */
}
if (tmp & HOST_RESET) {
dev_err(host->dev, "controller reset failed (0x%x)\n",
tmp);
return -EIO;
}
/*
* To perform host reset, OS should set HOST_RESET and poll until this
* bit is read to be "0". Reset must complete within 1 second, or the
* hardware should be considered fried.
*/
tmp = ata_wait_register(NULL, mmio + HOST_CTL, HOST_RESET,
HOST_RESET, 10, 1000);
if (tmp & HOST_RESET) {
dev_err(host->dev, "Controller reset failed (0x%x)\n",
tmp);
return -EIO;
}
/* turn on AHCI mode */
ahci_enable_ahci(mmio);
/* Turn on AHCI mode */
ahci_enable_ahci(mmio);
/* Some registers might be cleared on reset. Restore
* initial values.
*/
if (!(hpriv->flags & AHCI_HFLAG_NO_WRITE_TO_RO))
ahci_restore_initial_config(host);
} else
dev_info(host->dev, "skipping global host reset\n");
/* Some registers might be cleared on reset. Restore initial values. */
if (!(hpriv->flags & AHCI_HFLAG_NO_WRITE_TO_RO))
ahci_restore_initial_config(host);
return 0;
}

View File

@ -3802,11 +3802,7 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
return -ENODEV;
/* fail early if !ATA && !ATAPI to avoid issuing [P]IDENTIFY to PMP */
if (ata_class_enabled(new_class) &&
new_class != ATA_DEV_ATA &&
new_class != ATA_DEV_ATAPI &&
new_class != ATA_DEV_ZAC &&
new_class != ATA_DEV_SEMB) {
if (ata_class_enabled(new_class) && new_class == ATA_DEV_PMP) {
ata_dev_info(dev, "class mismatch %u != %u\n",
dev->class, new_class);
rc = -ENODEV;
@ -6142,13 +6138,11 @@ EXPORT_SYMBOL_GPL(ata_pci_device_resume);
* LOCKING:
* Inherited from platform layer (may sleep).
*/
int ata_platform_remove_one(struct platform_device *pdev)
void ata_platform_remove_one(struct platform_device *pdev)
{
struct ata_host *host = platform_get_drvdata(pdev);
ata_host_detach(host);
return 0;
}
EXPORT_SYMBOL_GPL(ata_platform_remove_one);

View File

@ -1817,9 +1817,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev,
verdict = ata_eh_speed_down_verdict(dev);
/* turn off NCQ? */
if ((verdict & ATA_EH_SPDN_NCQ_OFF) &&
(dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ |
ATA_DFLAG_NCQ_OFF)) == ATA_DFLAG_NCQ) {
if ((verdict & ATA_EH_SPDN_NCQ_OFF) && ata_ncq_enabled(dev)) {
dev->flags |= ATA_DFLAG_NCQ_OFF;
ata_dev_warn(dev, "NCQ disabled due to excessive errors\n");
goto done;
@ -3813,16 +3811,29 @@ void ata_eh_finish(struct ata_port *ap)
* generate sense data in this function,
* considering both err_mask and tf.
*/
if (qc->flags & ATA_QCFLAG_RETRY)
if (qc->flags & ATA_QCFLAG_RETRY) {
/*
* Since qc->err_mask is set, ata_eh_qc_retry()
* will not increment scmd->allowed, so upper
* layer will only retry the command if it has
* not already been retried too many times.
*/
ata_eh_qc_retry(qc);
else
} else {
ata_eh_qc_complete(qc);
}
} else {
if (qc->flags & ATA_QCFLAG_SENSE_VALID) {
ata_eh_qc_complete(qc);
} else {
/* feed zero TF to sense generation */
memset(&qc->result_tf, 0, sizeof(qc->result_tf));
/*
* Since qc->err_mask is not set,
* ata_eh_qc_retry() will increment
* scmd->allowed, so upper layer is guaranteed
* to retry the command.
*/
ata_eh_qc_retry(qc);
}
}

View File

@ -1023,7 +1023,6 @@ EXPORT_SYMBOL_GPL(dev_attr_sw_activity);
/**
* ata_change_queue_depth - Set a device maximum queue depth
* @ap: ATA port of the target device
* @dev: target ATA device
* @sdev: SCSI device to configure queue depth for
* @queue_depth: new queue depth
*
@ -1031,33 +1030,47 @@ EXPORT_SYMBOL_GPL(dev_attr_sw_activity);
* and libata.
*
*/
int ata_change_queue_depth(struct ata_port *ap, struct ata_device *dev,
struct scsi_device *sdev, int queue_depth)
int ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev,
int queue_depth)
{
struct ata_device *dev;
unsigned long flags;
int max_queue_depth;
if (!dev || !ata_dev_enabled(dev))
return sdev->queue_depth;
if (queue_depth < 1 || queue_depth == sdev->queue_depth)
return sdev->queue_depth;
/* NCQ enabled? */
spin_lock_irqsave(ap->lock, flags);
dev->flags &= ~ATA_DFLAG_NCQ_OFF;
if (queue_depth == 1 || !ata_ncq_enabled(dev)) {
dev = ata_scsi_find_dev(ap, sdev);
if (!dev || queue_depth < 1 || queue_depth == sdev->queue_depth) {
spin_unlock_irqrestore(ap->lock, flags);
return sdev->queue_depth;
}
/*
* Make sure that the queue depth requested does not exceed the device
* capabilities.
*/
max_queue_depth = min(ATA_MAX_QUEUE, sdev->host->can_queue);
max_queue_depth = min(max_queue_depth, ata_id_queue_depth(dev->id));
if (queue_depth > max_queue_depth) {
spin_unlock_irqrestore(ap->lock, flags);
return -EINVAL;
}
/*
* If NCQ is not supported by the device or if the target queue depth
* is 1 (to disable drive side command queueing), turn off NCQ.
*/
if (queue_depth == 1 || !ata_ncq_supported(dev)) {
dev->flags |= ATA_DFLAG_NCQ_OFF;
queue_depth = 1;
} else {
dev->flags &= ~ATA_DFLAG_NCQ_OFF;
}
spin_unlock_irqrestore(ap->lock, flags);
/* limit and apply queue depth */
queue_depth = min(queue_depth, sdev->host->can_queue);
queue_depth = min(queue_depth, ata_id_queue_depth(dev->id));
queue_depth = min(queue_depth, ATA_MAX_QUEUE);
if (sdev->queue_depth == queue_depth)
return -EINVAL;
if (queue_depth == sdev->queue_depth)
return sdev->queue_depth;
return scsi_change_queue_depth(sdev, queue_depth);
}
@ -1082,8 +1095,7 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
{
struct ata_port *ap = ata_shost_to_port(sdev->host);
return ata_change_queue_depth(ap, ata_scsi_find_dev(ap, sdev),
sdev, queue_depth);
return ata_change_queue_depth(ap, sdev, queue_depth);
}
EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth);

View File

@ -1122,7 +1122,7 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev)
if (dev->flags & ATA_DFLAG_AN)
set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events);
if (dev->flags & ATA_DFLAG_NCQ)
if (ata_ncq_supported(dev))
depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id));
depth = min(ATA_MAX_QUEUE, depth);
scsi_change_queue_depth(sdev, depth);

View File

@ -303,7 +303,7 @@ static struct platform_driver ixp4xx_pata_platform_driver = {
.of_match_table = ixp4xx_pata_of_match,
},
.probe = ixp4xx_pata_probe,
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
};
module_platform_driver(ixp4xx_pata_platform_driver);

View File

@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <scsi/scsi_host.h>
@ -804,9 +805,7 @@ static int octeon_cf_probe(struct platform_device *pdev)
struct resource *res_cs0, *res_cs1;
bool is_16bit;
const __be32 *cs_num;
struct property *reg_prop;
int n_addr, n_size, reg_len;
u64 reg;
struct device_node *node;
void __iomem *cs0;
void __iomem *cs1 = NULL;
@ -834,15 +833,10 @@ static int octeon_cf_probe(struct platform_device *pdev)
else
is_16bit = false;
n_addr = of_n_addr_cells(node);
n_size = of_n_size_cells(node);
reg_prop = of_find_property(node, "reg", &reg_len);
if (!reg_prop || reg_len < sizeof(__be32))
return -EINVAL;
cs_num = reg_prop->value;
cf_port->cs0 = be32_to_cpup(cs_num);
rv = of_property_read_reg(node, 0, &reg, NULL);
if (rv < 0)
return rv;
cf_port->cs0 = upper_32_bits(reg);
if (cf_port->is_true_ide) {
struct device_node *dma_node;
@ -884,13 +878,12 @@ static int octeon_cf_probe(struct platform_device *pdev)
cs1 = devm_ioremap(&pdev->dev, res_cs1->start,
resource_size(res_cs1));
if (!cs1)
return rv;
if (reg_len < (n_addr + n_size + 1) * sizeof(__be32))
return -EINVAL;
cs_num += n_addr + n_size;
cf_port->cs1 = be32_to_cpup(cs_num);
rv = of_property_read_reg(node, 1, &reg, NULL);
if (rv < 0)
return rv;
cf_port->cs1 = upper_32_bits(reg);
}
res_cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);

View File

@ -89,7 +89,7 @@ static struct platform_driver pata_of_platform_driver = {
.of_match_table = pata_of_platform_match,
},
.probe = pata_of_platform_probe,
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
};
module_platform_driver(pata_of_platform_driver);

View File

@ -1,13 +1,12 @@
/*
aten.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU General Public License.
aten.c is a low-level protocol driver for the ATEN EH-100
parallel port adapter. The EH-100 supports 4-bit and 8-bit
modes only. There is also an EH-132 which supports EPP mode
transfers. The EH-132 is not yet supported.
*/
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 1997-8 Grant R. Guenther <grant@torque.net>
*
* aten.c is a low-level protocol driver for the ATEN EH-100
* parallel port adapter. The EH-100 supports 4-bit and 8-bit
* modes only. There is also an EH-132 which supports EPP mode
* transfers. The EH-132 is not yet supported.
*/
#include <linux/module.h>
#include <linux/init.h>
@ -20,36 +19,36 @@
#define j44(a,b) ((((a>>4)&0x0f)|(b&0xf0))^0x88)
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
*/
/*
* cont = 0 - access the IDE register file
* cont = 1 - access the IDE command set
*/
static int cont_map[2] = { 0x08, 0x20 };
static void aten_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{ int r;
r = regr + cont_map[cont] + 0x80;
{
int r = regr + cont_map[cont] + 0x80;
w0(r); w2(0xe); w2(6); w0(val); w2(7); w2(6); w2(0xc);
}
static int aten_read_regr(struct pi_adapter *pi, int cont, int regr)
{
int a, b, r;
{ int a, b, r;
r = regr + cont_map[cont] + 0x40;
r = regr + cont_map[cont] + 0x40;
switch (pi->mode) {
case 0: w0(r); w2(0xe); w2(6);
case 0:
w0(r); w2(0xe); w2(6);
w2(7); w2(6); w2(0);
a = r1(); w0(0x10); b = r1(); w2(0xc);
return j44(a,b);
case 1: r |= 0x10;
w0(r); w2(0xe); w2(6); w0(0xff);
case 1:
r |= 0x10;
w0(r); w2(0xe); w2(6); w0(0xff);
w2(0x27); w2(0x26); w2(0x20);
a = r0();
w2(0x26); w2(0xc);
@ -59,27 +58,30 @@ static int aten_read_regr(struct pi_adapter *pi, int cont, int regr)
}
static void aten_read_block(struct pi_adapter *pi, char *buf, int count)
{ int k, a, b, c, d;
{
int k, a, b, c, d;
switch (pi->mode) {
case 0: w0(0x48); w2(0xe); w2(6);
for (k=0;k<count/2;k++) {
case 0:
w0(0x48); w2(0xe); w2(6);
for (k = 0; k < count / 2; k++) {
w2(7); w2(6); w2(2);
a = r1(); w0(0x58); b = r1();
w2(0); d = r1(); w0(0x48); c = r1();
buf[2*k] = j44(c,d);
buf[2*k+1] = j44(a,b);
buf[2 * k] = j44(c, d);
buf[2 * k + 1] = j44(a, b);
}
w2(0xc);
break;
case 1: w0(0x58); w2(0xe); w2(6);
for (k=0;k<count/2;k++) {
case 1:
w0(0x58); w2(0xe); w2(6);
for (k = 0; k < count / 2; k++) {
w2(0x27); w2(0x26); w2(0x22);
a = r0(); w2(0x20); b = r0();
buf[2*k] = b; buf[2*k+1] = a;
buf[2 * k] = b;
buf[2 * k + 1] = a;
}
w2(0x26); w2(0xc);
break;
@ -87,36 +89,37 @@ static void aten_read_block(struct pi_adapter *pi, char *buf, int count)
}
static void aten_write_block(struct pi_adapter *pi, char *buf, int count)
{ int k;
{
int k;
w0(0x88); w2(0xe); w2(6);
for (k=0;k<count/2;k++) {
w0(buf[2*k+1]); w2(0xe); w2(6);
w0(buf[2*k]); w2(7); w2(6);
for (k = 0; k < count / 2; k++) {
w0(buf[2 * k + 1]); w2(0xe); w2(6);
w0(buf[2 * k]); w2(7); w2(6);
}
w2(0xc);
}
static void aten_connect(struct pi_adapter *pi)
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(0xc);
{
pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(0xc);
}
static void aten_disconnect(struct pi_adapter *pi)
{ w0(pi->saved_r0);
w2(pi->saved_r2);
}
{
w0(pi->saved_r0);
w2(pi->saved_r2);
}
static void aten_log_adapter(struct pi_adapter *pi)
{
char *mode_string[2] = { "4-bit", "8-bit" };
{ char *mode_string[2] = {"4-bit","8-bit"};
dev_info(&pi->dev, "ATEN EH-100 at 0x%x, mode %d (%s), delay %d\n",
pi->port, pi->mode, mode_string[pi->mode], pi->delay);
dev_info(&pi->dev,
"ATEN EH-100 at 0x%x, mode %d (%s), delay %d\n",
pi->port, pi->mode, mode_string[pi->mode], pi->delay);
}
static struct pi_protocol aten = {

View File

@ -1,11 +1,10 @@
/*
bpck.c (c) 1996-8 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU General Public License.
bpck.c is a low-level protocol driver for the MicroSolutions
"backpack" parallel port IDE adapter.
*/
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 1996-1998 Grant R. Guenther <grant@torque.net>
*
* bpck.c is a low-level protocol driver for the MicroSolutions
* "backpack" parallel port IDE adapter.
*/
#include <linux/module.h>
#include <linux/init.h>
@ -29,59 +28,57 @@
#define j44(l,h) (((l>>3)&0x7)|((l>>4)&0x8)|((h<<1)&0x70)|(h&0x80))
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
cont = 2 - use internal bpck register addressing
*/
/*
* cont = 0 - access the IDE register file
* cont = 1 - access the IDE command set
* cont = 2 - use internal bpck register addressing
*/
static int cont_map[3] = { 0x40, 0x48, 0 };
static int bpck_read_regr(struct pi_adapter *pi, int cont, int regr)
{ int r, l, h;
{
int r, l, h;
r = regr + cont_map[cont];
switch (pi->mode) {
case 0: w0(r & 0xf); w0(r); t2(2); t2(4);
case 0:
w0(r & 0xf); w0(r); t2(2); t2(4);
l = r1();
t2(4);
h = r1();
return j44(l,h);
case 1: w0(r & 0xf); w0(r); t2(2);
e2(); t2(0x20);
t2(4);
h = r1();
return j44(l, h);
case 1:
w0(r & 0xf); w0(r); t2(2);
e2(); t2(0x20);
t2(4); h = r0();
t2(1); t2(0x20);
return h;
t2(1); t2(0x20);
return h;
case 2:
case 3:
case 4: w0(r); w2(9); w2(0); w2(0x20);
case 4:
w0(r); w2(9); w2(0); w2(0x20);
h = r4();
w2(0);
return h;
}
return -1;
}
}
static void bpck_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{ int r;
{
int r;
r = regr + cont_map[cont];
switch (pi->mode) {
case 0:
case 1: w0(r);
t2(2);
w0(val);
o2(); t2(4); t2(1);
break;
case 2:
case 3:
case 4: w0(r); w2(9); w2(0);
@ -97,210 +94,249 @@ static void bpck_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
#define RR(r) (bpck_read_regr(pi,2,r))
static void bpck_write_block(struct pi_adapter *pi, char *buf, int count)
{ int i;
{
int i;
switch (pi->mode) {
case 0: WR(4,0x40);
case 0:
WR(4, 0x40);
w0(0x40); t2(2); t2(1);
for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
WR(4,0);
for (i = 0; i < count; i++) {
w0(buf[i]);
t2(4);
}
WR(4, 0);
break;
case 1: WR(4,0x50);
w0(0x40); t2(2); t2(1);
for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
WR(4,0x10);
case 1:
WR(4, 0x50);
w0(0x40); t2(2); t2(1);
for (i = 0; i < count; i++) {
w0(buf[i]);
t2(4);
}
WR(4, 0x10);
break;
case 2: WR(4,0x48);
case 2:
WR(4, 0x48);
w0(0x40); w2(9); w2(0); w2(1);
for (i=0;i<count;i++) w4(buf[i]);
for (i = 0; i < count; i++)
w4(buf[i]);
w2(0);
WR(4,8);
WR(4, 8);
break;
case 3: WR(4,0x48);
w0(0x40); w2(9); w2(0); w2(1);
for (i=0;i<count/2;i++) w4w(((u16 *)buf)[i]);
w2(0);
WR(4,8);
break;
case 4: WR(4,0x48);
w0(0x40); w2(9); w2(0); w2(1);
for (i=0;i<count/4;i++) w4l(((u32 *)buf)[i]);
w2(0);
WR(4,8);
break;
case 3:
WR(4, 0x48);
w0(0x40); w2(9); w2(0); w2(1);
for (i = 0; i < count / 2; i++)
w4w(((u16 *)buf)[i]);
w2(0);
WR(4, 8);
break;
case 4:
WR(4, 0x48);
w0(0x40); w2(9); w2(0); w2(1);
for (i = 0; i < count / 4; i++)
w4l(((u32 *)buf)[i]);
w2(0);
WR(4, 8);
break;
}
}
static void bpck_read_block(struct pi_adapter *pi, char *buf, int count)
{ int i, l, h;
{
int i, l, h;
switch (pi->mode) {
case 0: WR(4,0x40);
case 0:
WR(4, 0x40);
w0(0x40); t2(2);
for (i=0;i<count;i++) {
t2(4); l = r1();
t2(4); h = r1();
buf[i] = j44(l,h);
for (i = 0; i < count; i++) {
t2(4); l = r1();
t2(4); h = r1();
buf[i] = j44(l, h);
}
WR(4,0);
WR(4, 0);
break;
case 1: WR(4,0x50);
case 1:
WR(4, 0x50);
w0(0x40); t2(2); t2(0x20);
for(i=0;i<count;i++) { t2(4); buf[i] = r0(); }
t2(1); t2(0x20);
WR(4,0x10);
for (i = 0; i < count; i++) {
t2(4);
buf[i] = r0();
}
t2(1); t2(0x20);
WR(4, 0x10);
break;
case 2: WR(4,0x48);
case 2:
WR(4, 0x48);
w0(0x40); w2(9); w2(0); w2(0x20);
for (i=0;i<count;i++) buf[i] = r4();
for (i = 0; i < count; i++)
buf[i] = r4();
w2(0);
WR(4,8);
WR(4, 8);
break;
case 3: WR(4,0x48);
w0(0x40); w2(9); w2(0); w2(0x20);
for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
w2(0);
WR(4,8);
break;
case 3:
WR(4, 0x48);
w0(0x40); w2(9); w2(0); w2(0x20);
for (i = 0; i < count / 2; i++)
((u16 *)buf)[i] = r4w();
w2(0);
WR(4, 8);
break;
case 4: WR(4,0x48);
w0(0x40); w2(9); w2(0); w2(0x20);
for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
w2(0);
WR(4,8);
break;
case 4:
WR(4, 0x48);
w0(0x40); w2(9); w2(0); w2(0x20);
for (i = 0; i < count / 4; i++)
((u32 *)buf)[i] = r4l();
w2(0);
WR(4, 8);
break;
}
}
static int bpck_probe_unit(struct pi_adapter *pi)
{ int o1, o0, f7, id;
{
int o1, o0, f7, id;
int t, s;
id = pi->unit;
s = 0;
w2(4); w2(0xe); r2(); t2(2);
w2(4); w2(0xe); r2(); t2(2);
o1 = r1()&0xf8;
o0 = r0();
w0(255-id); w2(4); w0(id);
t2(8); t2(8); t2(8);
t2(2); t = r1()&0xf8;
f7 = ((id % 8) == 7);
if ((f7) || (t != o1)) { t2(2); s = r1()&0xf8; }
if ((f7) || (t != o1)) {
t2(2);
s = r1() & 0xf8;
}
if ((t == o1) && ((!f7) || (s == o1))) {
w2(0x4c); w0(o0);
return 0;
return 0;
}
t2(8); w0(0); t2(2); w2(0x4c); w0(o0);
return 1;
}
static void bpck_connect(struct pi_adapter *pi)
{ pi->saved_r0 = r0();
{
pi->saved_r0 = r0();
w0(0xff-pi->unit); w2(4); w0(pi->unit);
t2(8); t2(8); t2(8);
t2(8); t2(8); t2(8);
t2(2); t2(2);
switch (pi->mode) {
case 0: t2(8); WR(4,0);
case 0:
t2(8); WR(4, 0);
break;
case 1: t2(8); WR(4,0x10);
case 1:
t2(8); WR(4, 0x10);
break;
case 2:
case 3:
case 4: w2(0); WR(4,8);
case 3:
case 4:
w2(0); WR(4, 8);
break;
}
WR(5,8);
/* if (pi->devtype == PI_PCD) { possibly wrong, purpose unknown */
WR(0x46,0x10); /* fiddle with ESS logic ??? */
WR(0x4c,0x38);
WR(0x4d,0x88);
WR(0x46,0xa0);
WR(0x41,0);
WR(0x4e,8);
/* }*/
/*
* Possibly wrong, purpose unknown (fiddle with ESS logic ???)
* if (pi->devtype == PI_PCD) {
*/
WR(0x46, 0x10);
WR(0x4c, 0x38);
WR(0x4d, 0x88);
WR(0x46, 0xa0);
WR(0x41, 0);
WR(0x4e, 8);
/* } */
}
static void bpck_disconnect(struct pi_adapter *pi)
{ w0(0);
if (pi->mode >= 2) { w2(9); w2(0); } else t2(2);
{
w0(0);
if (pi->mode >= 2) {
w2(9); w2(0);
} else {
t2(2);
}
w2(0x4c); w0(pi->saved_r0);
}
}
static void bpck_force_spp(struct pi_adapter *pi)
{
/* This fakes the EPP protocol to turn off EPP ... */
pi->saved_r0 = r0();
w0(0xff-pi->unit); w2(4); w0(pi->unit);
t2(8); t2(8); t2(8);
t2(2); t2(2);
/* This fakes the EPP protocol to turn off EPP ... */
{ pi->saved_r0 = r0();
w0(0xff-pi->unit); w2(4); w0(pi->unit);
t2(8); t2(8); t2(8);
t2(2); t2(2);
w2(0);
w0(4); w2(9); w2(0);
w0(0); w2(1); w2(3); w2(0);
w0(0); w2(9); w2(0);
w2(0x4c); w0(pi->saved_r0);
w2(0);
w0(4); w2(9); w2(0);
w0(0); w2(1); w2(3); w2(0);
w0(0); w2(9); w2(0);
w2(0x4c); w0(pi->saved_r0);
}
#define TEST_LEN 16
static int bpck_test_proto(struct pi_adapter *pi)
{ int i, e, l, h, om;
{
int i, e, l, h, om;
char buf[TEST_LEN];
bpck_force_spp(pi);
switch (pi->mode) {
case 0: bpck_connect(pi);
WR(0x13,0x7f);
case 0:
bpck_connect(pi);
WR(0x13, 0x7f);
w0(0x13); t2(2);
for(i=0;i<TEST_LEN;i++) {
t2(4); l = r1();
t2(4); h = r1();
buf[i] = j44(l,h);
for (i = 0; i < TEST_LEN; i++) {
t2(4); l = r1();
t2(4); h = r1();
buf[i] = j44(l, h);
}
bpck_disconnect(pi);
break;
case 1: bpck_connect(pi);
WR(0x13,0x7f);
w0(0x13); t2(2); t2(0x20);
for(i=0;i<TEST_LEN;i++) { t2(4); buf[i] = r0(); }
t2(1); t2(0x20);
case 1:
bpck_connect(pi);
WR(0x13, 0x7f);
w0(0x13); t2(2); t2(0x20);
for (i = 0; i < TEST_LEN; i++) {
t2(4);
buf[i] = r0();
}
t2(1); t2(0x20);
bpck_disconnect(pi);
break;
case 2:
case 3:
case 4: om = pi->mode;
case 4:
om = pi->mode;
pi->mode = 0;
bpck_connect(pi);
WR(7,3);
WR(4,8);
WR(7, 3);
WR(4, 8);
bpck_disconnect(pi);
pi->mode = om;
@ -308,34 +344,44 @@ static int bpck_test_proto(struct pi_adapter *pi)
w0(0x13); w2(9); w2(1); w0(0); w2(3); w2(0); w2(0xe0);
switch (pi->mode) {
case 2: for (i=0;i<TEST_LEN;i++) buf[i] = r4();
break;
case 3: for (i=0;i<TEST_LEN/2;i++) ((u16 *)buf)[i] = r4w();
break;
case 4: for (i=0;i<TEST_LEN/4;i++) ((u32 *)buf)[i] = r4l();
break;
case 2:
for (i = 0; i < TEST_LEN; i++)
buf[i] = r4();
break;
case 3:
for (i = 0; i < TEST_LEN / 2; i++)
((u16 *)buf)[i] = r4w();
break;
case 4:
for (i = 0; i < TEST_LEN / 4; i++)
((u32 *)buf)[i] = r4l();
break;
}
w2(0);
WR(7,0);
WR(7, 0);
bpck_disconnect(pi);
break;
}
dev_dbg(&pi->dev, "bpck: 0x%x unit %d mode %d: ",
pi->port, pi->unit, pi->mode);
print_hex_dump_debug("bpck: ", DUMP_PREFIX_NONE, TEST_LEN, 1, buf, TEST_LEN, false);
print_hex_dump_debug("bpck: ", DUMP_PREFIX_NONE, TEST_LEN, 1, buf,
TEST_LEN, false);
e = 0;
for (i=0;i<TEST_LEN;i++) if (buf[i] != (i+1)) e++;
for (i = 0; i < TEST_LEN; i++) {
if (buf[i] != i + 1)
e++;
}
return e;
}
static void bpck_read_eeprom(struct pi_adapter *pi, char *buf)
{ int i, j, k, p, v, f, om, od;
{
int i, j, k, p, v, f, om, od;
bpck_force_spp(pi);
@ -343,77 +389,97 @@ static void bpck_read_eeprom(struct pi_adapter *pi, char *buf)
pi->mode = 0; pi->delay = 6;
bpck_connect(pi);
WR(4,0);
for (i=0;i<64;i++) {
WR(6,8);
WR(6,0xc);
p = 0x100;
for (k=0;k<9;k++) {
f = (((i + 0x180) & p) != 0) * 2;
WR(6,f+0xc);
WR(6,f+0xd);
WR(6,f+0xc);
p = (p >> 1);
}
for (j=0;j<2;j++) {
v = 0;
for (k=0;k<8;k++) {
WR(6,0xc);
WR(6,0xd);
WR(6,0xc);
f = RR(0);
v = 2*v + (f == 0x84);
WR(4, 0);
for (i = 0; i < 64; i++) {
WR(6, 8);
WR(6, 0xc);
p = 0x100;
for (k = 0; k < 9; k++) {
f = (((i + 0x180) & p) != 0) * 2;
WR(6, f + 0xc);
WR(6, f + 0xd);
WR(6, f + 0xc);
p = (p >> 1);
}
for (j = 0; j < 2; j++) {
v = 0;
for (k = 0; k < 8; k++) {
WR(6, 0xc);
WR(6, 0xd);
WR(6, 0xc);
f = RR(0);
v = 2 * v + (f == 0x84);
}
buf[2 * i + 1 - j] = v;
}
buf[2*i+1-j] = v;
}
}
WR(6,8);
WR(6,0);
WR(5,8);
WR(6, 8);
WR(6, 0);
WR(5, 8);
bpck_disconnect(pi);
if (om >= 2) {
bpck_connect(pi);
WR(7,3);
WR(4,8);
bpck_disconnect(pi);
bpck_connect(pi);
WR(7, 3);
WR(4, 8);
bpck_disconnect(pi);
}
pi->mode = om; pi->delay = od;
}
static int bpck_test_port(struct pi_adapter *pi) /* check for 8-bit port */
{ int i, r, m;
static int bpck_test_port(struct pi_adapter *pi)
{
int i, r, m;
/* Check for 8-bit port */
w2(0x2c); i = r0(); w0(255-i); r = r0(); w0(i);
m = -1;
if (r == i) m = 2;
if (r == (255-i)) m = 0;
if (r == i)
m = 2;
if (r == (255-i))
m = 0;
w2(0xc); i = r0(); w0(255-i); r = r0(); w0(i);
if (r != (255-i)) m = -1;
if (m == 0) { w2(6); w2(0xc); r = r0(); w0(0xaa); w0(r); w0(0xaa); }
if (m == 2) { w2(0x26); w2(0xc); }
w2(0xc);
i = r0();
w0(255-i);
r = r0();
w0(i);
if (r != (255-i))
m = -1;
if (m == 0) {
w2(6);
w2(0xc);
r = r0();
w0(0xaa);
w0(r);
w0(0xaa);
}
if (m == 2) {
w2(0x26);
w2(0xc);
}
if (m == -1)
return 0;
if (m == -1) return 0;
return 5;
}
static void bpck_log_adapter(struct pi_adapter *pi)
{ char *mode_string[5] = { "4-bit","8-bit","EPP-8",
"EPP-16","EPP-32" };
{
char *mode_str[5] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" };
char scratch[128];
bpck_read_eeprom(pi,scratch);
print_hex_dump_bytes("bpck EEPROM: ", DUMP_PREFIX_NONE, scratch, 128);
dev_info(&pi->dev, "backpack %8.8s unit %d at 0x%x, mode %d (%s), delay %d\n",
dev_info(&pi->dev,
"backpack %8.8s unit %d at 0x%x, mode %d (%s), delay %d\n",
&scratch[110], pi->unit, pi->port, pi->mode,
mode_string[pi->mode], pi->delay);
mode_str[pi->mode], pi->delay);
}
static struct pi_protocol bpck = {

View File

@ -1,15 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
backpack.c (c) 2001 Micro Solutions Inc.
Released under the terms of the GNU General Public license
backpack.c is a low-level protocol driver for the Micro Solutions
"BACKPACK" parallel port IDE adapter
(Works on Series 6 drives)
Written by: Ken Hahn (linux-dev@micro-solutions.com)
Clive Turvey (linux-dev@micro-solutions.com)
*/
* (c) 2001 Micro Solutions Inc.
*
* backpack.c is a low-level protocol driver for the Micro Solutions
* "BACKPACK" parallel port IDE adapter (works on Series 6 drives).
*
* Written by: Ken Hahn (linux-dev@micro-solutions.com)
* Clive Turvey (linux-dev@micro-solutions.com)
*/
#include <linux/module.h>
#include <linux/init.h>
@ -326,11 +324,14 @@ static int bpck6_open(struct pi_adapter *pi)
if (j != k)
goto fail;
if (i & 4) // EPP
if (i & 4) {
/* EPP */
parport_frob_control(pi->pardev->port,
PARPORT_CONTROL_SELECT | PARPORT_CONTROL_INIT, 0);
else // PPC/ECP
} else {
/* PPC/ECP */
parport_frob_control(pi->pardev->port, PARPORT_CONTROL_SELECT, 0);
}
pi->private = 0;
@ -347,17 +348,20 @@ static int bpck6_open(struct pi_adapter *pi)
parport_write_control(pi->pardev->port, pi->saved_r2);
parport_write_data(pi->pardev->port, pi->saved_r0);
return 0; // FAIL
return 0;
}
static void bpck6_deselect(struct pi_adapter *pi)
{
if (mode_map[pi->mode] & 4) // EPP
if (mode_map[pi->mode] & 4) {
/* EPP */
parport_frob_control(pi->pardev->port, PARPORT_CONTROL_INIT,
PARPORT_CONTROL_INIT);
else // PPC/ECP
PARPORT_CONTROL_INIT);
} else {
/* PPC/ECP */
parport_frob_control(pi->pardev->port, PARPORT_CONTROL_SELECT,
PARPORT_CONTROL_SELECT);
PARPORT_CONTROL_SELECT);
}
parport_write_data(pi->pardev->port, pi->saved_r0);
parport_write_control(pi->pardev->port,
@ -386,7 +390,8 @@ static void bpck6_disconnect(struct pi_adapter *pi)
bpck6_deselect(pi);
}
static int bpck6_test_port(struct pi_adapter *pi) /* check for 8-bit port */
/* check for 8-bit port */
static int bpck6_test_port(struct pi_adapter *pi)
{
dev_dbg(&pi->dev, "PARPORT indicates modes=%x for lp=0x%lx\n",
pi->pardev->port->modes, pi->pardev->port->base);
@ -413,28 +418,26 @@ static int bpck6_probe_unit(struct pi_adapter *pi)
dev_dbg(&pi->dev, "ppc_open returned %2x\n", out);
if(out)
{
if (out) {
bpck6_deselect(pi);
dev_dbg(&pi->dev, "leaving probe\n");
pi->mode = saved_mode;
return(1);
return 1;
}
else
{
dev_dbg(&pi->dev, "Failed open\n");
pi->mode = saved_mode;
return(0);
}
dev_dbg(&pi->dev, "Failed open\n");
pi->mode = saved_mode;
return 0;
}
static void bpck6_log_adapter(struct pi_adapter *pi)
{
char *mode_string[5]=
{"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
char *mode_string[5] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" };
dev_info(&pi->dev, "Micro Solutions BACKPACK Drive unit %d at 0x%x, mode:%d (%s), delay %d\n",
pi->unit, pi->port, pi->mode, mode_string[pi->mode], pi->delay);
dev_info(&pi->dev,
"Micro Solutions BACKPACK Drive unit %d at 0x%x, mode:%d (%s), delay %d\n",
pi->unit, pi->port, pi->mode, mode_string[pi->mode], pi->delay);
}
static struct pi_protocol bpck6 = {

View File

@ -1,12 +1,11 @@
/*
comm.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU General Public License.
comm.c is a low-level protocol driver for some older models
of the DataStor "Commuter" parallel to IDE adapter. Some of
the parallel port devices marketed by Arista currently
use this adapter.
*/
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 1997-1998 Grant R. Guenther <grant@torque.net>
*
* comm.c is a low-level protocol driver for some older models of the DataStor
* "Commuter" parallel to IDE adapter. Some of the parallel port devices
* marketed by Arista currently use this adapter.
*/
#include <linux/module.h>
#include <linux/init.h>
@ -17,165 +16,172 @@
#include <asm/io.h>
#include "pata_parport.h"
/* mode codes: 0 nybble reads, 8-bit writes
1 8-bit reads and writes
2 8-bit EPP mode
*/
/*
* mode codes: 0 nybble reads, 8-bit writes
* 1 8-bit reads and writes
* 2 8-bit EPP mode
*/
#define j44(a,b) (((a>>3)&0x0f)|((b<<1)&0xf0))
#define j44(a, b) (((a >> 3) & 0x0f) | ((b << 1) & 0xf0))
#define P1 w2(5);w2(0xd);w2(0xd);w2(5);w2(4);
#define P2 w2(5);w2(7);w2(7);w2(5);w2(4);
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
*/
/*
* cont = 0 - access the IDE register file
* cont = 1 - access the IDE command set
*/
static int cont_map[2] = { 0x08, 0x10 };
static int comm_read_regr(struct pi_adapter *pi, int cont, int regr)
{ int l, h, r;
{
int l, h, r;
r = regr + cont_map[cont];
switch (pi->mode) {
switch (pi->mode) {
case 0:
w0(r); P1; w0(0);
w2(6); l = r1(); w0(0x80); h = r1(); w2(4);
return j44(l, h);
case 0: w0(r); P1; w0(0);
w2(6); l = r1(); w0(0x80); h = r1(); w2(4);
return j44(l,h);
case 1: w0(r+0x20); P1;
w0(0); w2(0x26); h = r0(); w2(4);
return h;
case 1:
w0(r+0x20); P1;
w0(0); w2(0x26); h = r0(); w2(4);
return h;
case 2:
case 3:
case 4: w3(r+0x20); (void)r1();
w2(0x24); h = r4(); w2(4);
return h;
case 4:
w3(r+0x20); (void)r1();
w2(0x24); h = r4(); w2(4);
return h;
}
}
return -1;
}
return -1;
}
static void comm_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{
int r = regr + cont_map[cont];
{ int r;
r = regr + cont_map[cont];
switch (pi->mode) {
case 0:
case 1: w0(r); P1; w0(val); P2;
switch (pi->mode) {
case 0:
case 1:
w0(r); P1; w0(val); P2;
break;
case 2:
case 3:
case 4: w3(r); (void)r1(); w4(val);
break;
}
case 4:
w3(r); (void)r1(); w4(val);
break;
}
}
static void comm_connect(struct pi_adapter *pi)
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(4); w0(0xff); w2(6);
w2(4); w0(0xaa); w2(6);
w2(4); w0(0x00); w2(6);
w2(4); w0(0x87); w2(6);
w2(4); w0(0xe0); w2(0xc); w2(0xc); w2(4);
{
pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(4); w0(0xff); w2(6);
w2(4); w0(0xaa); w2(6);
w2(4); w0(0x00); w2(6);
w2(4); w0(0x87); w2(6);
w2(4); w0(0xe0); w2(0xc); w2(0xc); w2(4);
}
static void comm_disconnect(struct pi_adapter *pi)
{ w2(0); w2(0); w2(0); w2(4);
{
w2(0); w2(0); w2(0); w2(4);
w0(pi->saved_r0);
w2(pi->saved_r2);
}
w2(pi->saved_r2);
}
static void comm_read_block(struct pi_adapter *pi, char *buf, int count)
{
int i, l, h;
{ int i, l, h;
switch (pi->mode) {
case 0: w0(0x48); P1;
for(i=0;i<count;i++) {
w0(0); w2(6); l = r1();
w0(0x80); h = r1(); w2(4);
buf[i] = j44(l,h);
}
break;
case 1: w0(0x68); P1; w0(0);
for(i=0;i<count;i++) {
w2(0x26); buf[i] = r0(); w2(0x24);
}
switch (pi->mode) {
case 0:
w0(0x48); P1;
for (i = 0; i < count; i++) {
w0(0); w2(6); l = r1();
w0(0x80); h = r1(); w2(4);
buf[i] = j44(l, h);
}
break;
case 1:
w0(0x68); P1; w0(0);
for (i = 0; i < count; i++) {
w2(0x26);
buf[i] = r0();
w2(0x24);
}
w2(4);
break;
case 2: w3(0x68); (void)r1(); w2(0x24);
for (i=0;i<count;i++) buf[i] = r4();
case 2:
w3(0x68); (void)r1(); w2(0x24);
for (i = 0; i < count; i++)
buf[i] = r4();
w2(4);
break;
case 3:
w3(0x68); (void)r1(); w2(0x24);
for (i = 0; i < count / 2; i++)
((u16 *)buf)[i] = r4w();
w2(4);
break;
case 4:
w3(0x68); (void)r1(); w2(0x24);
for (i = 0; i < count / 4; i++)
((u32 *)buf)[i] = r4l();
w2(4);
break;
case 3: w3(0x68); (void)r1(); w2(0x24);
for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
w2(4);
break;
case 4: w3(0x68); (void)r1(); w2(0x24);
for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
w2(4);
break;
}
}
/* NB: Watch out for the byte swapped writes ! */
static void comm_write_block(struct pi_adapter *pi, char *buf, int count)
{
int k;
{ int k;
switch (pi->mode) {
case 0:
case 1: w0(0x68); P1;
for (k=0;k<count;k++) {
w2(5); w0(buf[k^1]); w2(7);
}
w2(5); w2(4);
break;
case 2: w3(0x48); (void)r1();
for (k=0;k<count;k++) w4(buf[k^1]);
break;
case 3: w3(0x48); (void)r1();
switch (pi->mode) {
case 0:
case 1:
w0(0x68); P1;
for (k = 0; k < count; k++) {
w2(5);
w0(buf[k ^ 1]);
w2(7);
}
w2(5); w2(4);
break;
case 2:
w3(0x48); (void)r1();
for (k = 0; k < count; k++)
w4(buf[k ^ 1]);
break;
case 3:
w3(0x48); (void)r1();
for (k = 0; k < count / 2; k++)
w4w(swab16(((u16 *)buf)[k]));
break;
case 4: w3(0x48); (void)r1();
break;
case 4:
w3(0x48); (void)r1();
for (k = 0; k < count / 4; k++)
w4l(swab16(((u16 *)buf)[2 * k]) |
swab16(((u16 *)buf)[2 * k + 1]) << 16);
break;
break;
}
}
static void comm_log_adapter(struct pi_adapter *pi)
{ char *mode_string[5] = {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
{ char *mode_string[5] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" };
dev_info(&pi->dev, "DataStor Commuter at 0x%x, mode %d (%s), delay %d\n",
pi->port, pi->mode, mode_string[pi->mode], pi->delay);
dev_info(&pi->dev,
"DataStor Commuter at 0x%x, mode %d (%s), delay %d\n",
pi->port, pi->mode, mode_string[pi->mode], pi->delay);
}
static struct pi_protocol comm = {

View File

@ -1,11 +1,10 @@
/*
dstr.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU General Public License.
dstr.c is a low-level protocol driver for the
DataStor EP2000 parallel to IDE adapter chip.
*/
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 1997-1998 Grant R. Guenther <grant@torque.net>
*
* dstr.c is a low-level protocol driver for the DataStor EP2000 parallel
* to IDE adapter chip.
*/
#include <linux/module.h>
#include <linux/init.h>
@ -16,178 +15,202 @@
#include <asm/io.h>
#include "pata_parport.h"
/* mode codes: 0 nybble reads, 8-bit writes
1 8-bit reads and writes
2 8-bit EPP mode
3 EPP-16
4 EPP-32
*/
/*
* mode codes: 0 nybble reads, 8-bit writes
* 1 8-bit reads and writes
* 2 8-bit EPP mode
* 3 EPP-16
* 4 EPP-32
*/
#define j44(a,b) (((a>>3)&0x07)|((~a>>4)&0x08)|((b<<1)&0x70)|((~b)&0x80))
#define j44(a, b) (((a >> 3) & 0x07) | ((~a >> 4) & 0x08) | \
((b << 1) & 0x70) | ((~b) & 0x80))
#define P1 w2(5);w2(0xd);w2(5);w2(4);
#define P2 w2(5);w2(7);w2(5);w2(4);
#define P3 w2(6);w2(4);w2(6);w2(4);
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
*/
/*
* cont = 0 - access the IDE register file
* cont = 1 - access the IDE command set
*/
static int cont_map[2] = { 0x20, 0x40 };
static int dstr_read_regr(struct pi_adapter *pi, int cont, int regr)
{
int a, b, r;
{ int a, b, r;
r = regr + cont_map[cont];
r = regr + cont_map[cont];
w0(0x81); P1;
if (pi->mode) { w0(0x11); } else { w0(1); }
if (pi->mode)
w0(0x11);
else
w0(1);
P2; w0(r); P1;
switch (pi->mode) {
case 0: w2(6); a = r1(); w2(4); w2(6); b = r1(); w2(4);
return j44(a,b);
case 1: w0(0); w2(0x26); a = r0(); w2(4);
return a;
switch (pi->mode) {
case 0:
w2(6); a = r1(); w2(4); w2(6); b = r1(); w2(4);
return j44(a, b);
case 1:
w0(0); w2(0x26); a = r0(); w2(4);
return a;
case 2:
case 3:
case 4: w2(0x24); a = r4(); w2(4);
return a;
case 4:
w2(0x24); a = r4(); w2(4);
return a;
}
}
return -1;
}
static void dstr_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{ int r;
r = regr + cont_map[cont];
w0(0x81); P1;
if (pi->mode >= 2) { w0(0x11); } else { w0(1); }
P2; w0(r); P1;
switch (pi->mode) {
case 0:
case 1: w0(val); w2(5); w2(7); w2(5); w2(4);
break;
case 2:
case 3:
case 4: w4(val);
break;
}
return -1;
}
#define CCP(x) w0(0xff);w2(0xc);w2(4);\
w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);w0(0x78);\
w0(x);w2(5);w2(4);
static void dstr_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{
int r = regr + cont_map[cont];
w0(0x81); P1;
if (pi->mode >= 2)
w0(0x11);
else
w0(1);
P2; w0(r); P1;
switch (pi->mode) {
case 0:
case 1:
w0(val); w2(5); w2(7); w2(5); w2(4);
break;
case 2:
case 3:
case 4:
w4(val);
break;
}
}
#define CCP(x) \
do { \
w0(0xff); w2(0xc); w2(4); \
w0(0xaa); w0(0x55); w0(0); w0(0xff); \
w0(0x87); w0(0x78); \
w0(x); w2(5); w2(4); \
} while (0)
static void dstr_connect(struct pi_adapter *pi)
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(4); CCP(0xe0); w0(0xff);
{
pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(4); CCP(0xe0); w0(0xff);
}
static void dstr_disconnect(struct pi_adapter *pi)
{ CCP(0x30);
w0(pi->saved_r0);
w2(pi->saved_r2);
}
{
CCP(0x30);
w0(pi->saved_r0);
w2(pi->saved_r2);
}
static void dstr_read_block(struct pi_adapter *pi, char *buf, int count)
{ int k, a, b;
{
int k, a, b;
w0(0x81); P1;
if (pi->mode) { w0(0x19); } else { w0(9); }
if (pi->mode)
w0(0x19);
else
w0(9);
P2; w0(0x82); P1; P3; w0(0x20); P1;
switch (pi->mode) {
case 0: for (k=0;k<count;k++) {
w2(6); a = r1(); w2(4);
w2(6); b = r1(); w2(4);
buf[k] = j44(a,b);
}
break;
case 1: w0(0);
for (k=0;k<count;k++) {
w2(0x26); buf[k] = r0(); w2(0x24);
}
w2(4);
break;
case 2: w2(0x24);
for (k=0;k<count;k++) buf[k] = r4();
w2(4);
break;
case 3: w2(0x24);
for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
w2(4);
break;
case 4: w2(0x24);
for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
w2(4);
break;
}
switch (pi->mode) {
case 0:
for (k = 0; k < count; k++) {
w2(6); a = r1(); w2(4);
w2(6); b = r1(); w2(4);
buf[k] = j44(a, b);
}
break;
case 1:
w0(0);
for (k = 0; k < count; k++) {
w2(0x26);
buf[k] = r0();
w2(0x24);
}
w2(4);
break;
case 2:
w2(0x24);
for (k = 0; k < count; k++)
buf[k] = r4();
w2(4);
break;
case 3:
w2(0x24);
for (k = 0; k < count / 2; k++)
((u16 *)buf)[k] = r4w();
w2(4);
break;
case 4:
w2(0x24);
for (k = 0; k < count / 4; k++)
((u32 *)buf)[k] = r4l();
w2(4);
break;
}
}
static void dstr_write_block(struct pi_adapter *pi, char *buf, int count)
{
int k;
{ int k;
w0(0x81); P1;
if (pi->mode)
w0(0x19);
else
w0(9);
P2; w0(0x82); P1; P3; w0(0x20); P1;
w0(0x81); P1;
if (pi->mode) { w0(0x19); } else { w0(9); }
P2; w0(0x82); P1; P3; w0(0x20); P1;
switch (pi->mode) {
case 0:
case 1: for (k=0;k<count;k++) {
w2(5); w0(buf[k]); w2(7);
}
w2(5); w2(4);
break;
case 2: w2(0xc5);
for (k=0;k<count;k++) w4(buf[k]);
switch (pi->mode) {
case 0:
case 1:
for (k = 0; k < count; k++) {
w2(5);
w0(buf[k]);
w2(7);
}
w2(5); w2(4);
break;
case 2:
w2(0xc5);
for (k = 0; k < count; k++)
w4(buf[k]);
w2(0xc4);
break;
case 3: w2(0xc5);
for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
w2(0xc4);
break;
case 4: w2(0xc5);
for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
w2(0xc4);
break;
}
break;
case 3:
w2(0xc5);
for (k = 0; k < count / 2; k++)
w4w(((u16 *)buf)[k]);
w2(0xc4);
break;
case 4:
w2(0xc5);
for (k = 0; k < count / 4; k++)
w4l(((u32 *)buf)[k]);
w2(0xc4);
break;
}
}
static void dstr_log_adapter(struct pi_adapter *pi)
{ char *mode_string[5] = {"4-bit","8-bit","EPP-8",
"EPP-16","EPP-32"};
{
char *mode_string[5] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" };
dev_info(&pi->dev, "DataStor EP2000 at 0x%x, mode %d (%s), delay %d\n",
pi->port, pi->mode, mode_string[pi->mode], pi->delay);
dev_info(&pi->dev,
"DataStor EP2000 at 0x%x, mode %d (%s), delay %d\n",
pi->port, pi->mode, mode_string[pi->mode], pi->delay);
}
static struct pi_protocol dstr = {

View File

@ -1,13 +1,12 @@
/*
epat.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU General Public License.
This is the low level protocol driver for the EPAT parallel
to IDE adapter from Shuttle Technologies. This adapter is
used in many popular parallel port disk products such as the
SyQuest EZ drives, the Avatar Shark and the Imation SuperDisk.
*/
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 1997-1998 Grant R. Guenther <grant@torque.net>
*
* This is the low level protocol driver for the EPAT parallel
* to IDE adapter from Shuttle Technologies. This adapter is
* used in many popular parallel port disk products such as the
* SyQuest EZ drives, the Avatar Shark and the Imation SuperDisk.
*/
#include <linux/module.h>
#include <linux/init.h>
@ -18,276 +17,313 @@
#include <asm/io.h>
#include "pata_parport.h"
#define j44(a,b) (((a>>4)&0x0f)+(b&0xf0))
#define j53(a,b) (((a>>3)&0x1f)+((b<<4)&0xe0))
#define j44(a, b) (((a >> 4) & 0x0f) + (b & 0xf0))
#define j53(a, b) (((a >> 3) & 0x1f) + ((b << 4) & 0xe0))
static int epatc8;
module_param(epatc8, int, 0);
MODULE_PARM_DESC(epatc8, "support for the Shuttle EP1284 chip, "
"used in any recent Imation SuperDisk (LS-120) drive.");
/* cont = 0 IDE register file
cont = 1 IDE control registers
cont = 2 internal EPAT registers
*/
MODULE_PARM_DESC(epatc8,
"support for the Shuttle EP1284 chip, "
"used in any recent Imation SuperDisk (LS-120) drive.");
/*
* cont = 0 IDE register file
* cont = 1 IDE control registers
* cont = 2 internal EPAT registers
*/
static int cont_map[3] = { 0x18, 0x10, 0 };
static void epat_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{
int r = regr + cont_map[cont];
{ int r;
switch (pi->mode) {
case 0:
case 1:
case 2:
w0(0x60+r); w2(1); w0(val); w2(4);
break;
case 3:
case 4:
case 5:
w3(0x40+r); w4(val);
break;
}
}
static int epat_read_regr(struct pi_adapter *pi, int cont, int regr)
{
int a, b, r;
r = regr + cont_map[cont];
switch (pi->mode) {
case 0:
case 1:
case 2: w0(0x60+r); w2(1); w0(val); w2(4);
break;
case 3:
case 4:
case 5: w3(0x40+r); w4(val);
break;
}
}
static int epat_read_regr(struct pi_adapter *pi, int cont, int regr)
{ int a, b, r;
r = regr + cont_map[cont];
switch (pi->mode) {
case 0: w0(r); w2(1); w2(3);
w0(r); w2(1); w2(3);
a = r1(); w2(4); b = r1();
return j44(a,b);
case 1: w0(0x40+r); w2(1); w2(4);
return j44(a, b);
case 1:
w0(0x40+r); w2(1); w2(4);
a = r1(); b = r2(); w0(0xff);
return j53(a,b);
case 2: w0(0x20+r); w2(1); w2(0x25);
return j53(a, b);
case 2:
w0(0x20+r); w2(1); w2(0x25);
a = r0(); w2(4);
return a;
case 3:
case 4:
case 5: w3(r); w2(0x24); a = r4(); w2(4);
case 5:
w3(r); w2(0x24); a = r4(); w2(4);
return a;
}
return -1; /* never gets here */
}
static void epat_read_block(struct pi_adapter *pi, char *buf, int count)
{ int k, ph, a, b;
{
int k, ph, a, b;
switch (pi->mode) {
case 0: w0(7); w2(1); w2(3); w0(0xff);
case 0:
w0(7); w2(1); w2(3); w0(0xff);
ph = 0;
for(k=0;k<count;k++) {
if (k == count-1) w0(0xfd);
w2(6+ph); a = r1();
if (a & 8) b = a;
else { w2(4+ph); b = r1(); }
buf[k] = j44(a,b);
for (k = 0; k < count; k++) {
if (k == count-1)
w0(0xfd);
w2(6 + ph); a = r1();
if (a & 8) {
b = a;
} else {
w2(4+ph); b = r1();
}
buf[k] = j44(a, b);
ph = 1 - ph;
}
w0(0); w2(4);
break;
case 1: w0(0x47); w2(1); w2(5); w0(0xff);
case 1:
w0(0x47); w2(1); w2(5); w0(0xff);
ph = 0;
for(k=0;k<count;k++) {
if (k == count-1) w0(0xfd);
w2(4+ph);
for (k = 0; k < count; k++) {
if (k == count - 1)
w0(0xfd);
w2(4 + ph);
a = r1(); b = r2();
buf[k] = j53(a,b);
buf[k] = j53(a, b);
ph = 1 - ph;
}
w0(0); w2(4);
break;
case 2: w0(0x27); w2(1); w2(0x25); w0(0);
case 2:
w0(0x27); w2(1); w2(0x25); w0(0);
ph = 0;
for(k=0;k<count-1;k++) {
w2(0x24+ph);
for (k = 0; k < count - 1; k++) {
w2(0x24 + ph);
buf[k] = r0();
ph = 1 - ph;
}
w2(0x26); w2(0x27); buf[count-1] = r0();
w2(0x26); w2(0x27);
buf[count - 1] = r0();
w2(0x25); w2(4);
break;
case 3: w3(0x80); w2(0x24);
for(k=0;k<count-1;k++) buf[k] = r4();
w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
case 3:
w3(0x80); w2(0x24);
for (k = 0; k < count - 1; k++)
buf[k] = r4();
w2(4); w3(0xa0); w2(0x24);
buf[count - 1] = r4();
w2(4);
break;
case 4: w3(0x80); w2(0x24);
for(k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
buf[count-2] = r4();
w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
case 4:
w3(0x80); w2(0x24);
for (k = 0; k < count / 2 - 1; k++)
((u16 *)buf)[k] = r4w();
buf[count - 2] = r4();
w2(4); w3(0xa0); w2(0x24);
buf[count - 1] = r4();
w2(4);
break;
case 5: w3(0x80); w2(0x24);
for(k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
for(k=count-4;k<count-1;k++) buf[k] = r4();
w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
case 5:
w3(0x80); w2(0x24);
for (k = 0; k < count / 4 - 1; k++)
((u32 *)buf)[k] = r4l();
for (k = count - 4; k < count - 1; k++)
buf[k] = r4();
w2(4); w3(0xa0); w2(0x24);
buf[count - 1] = r4();
w2(4);
break;
}
}
static void epat_write_block(struct pi_adapter *pi, char *buf, int count)
{ int ph, k;
{
int ph, k;
switch (pi->mode) {
case 0:
case 1:
case 2: w0(0x67); w2(1); w2(5);
case 2:
w0(0x67); w2(1); w2(5);
ph = 0;
for(k=0;k<count;k++) {
for (k = 0; k < count; k++) {
w0(buf[k]);
w2(4+ph);
w2(4 + ph);
ph = 1 - ph;
}
w2(7); w2(4);
break;
case 3: w3(0xc0);
for(k=0;k<count;k++) w4(buf[k]);
case 3:
w3(0xc0);
for (k = 0; k < count; k++)
w4(buf[k]);
w2(4);
break;
case 4: w3(0xc0);
for(k=0;k<(count/2);k++) w4w(((u16 *)buf)[k]);
case 4:
w3(0xc0);
for (k = 0; k < count / 2; k++)
w4w(((u16 *)buf)[k]);
w2(4);
break;
case 5: w3(0xc0);
for(k=0;k<(count/4);k++) w4l(((u32 *)buf)[k]);
case 5:
w3(0xc0);
for (k = 0; k < count / 4; k++)
w4l(((u32 *)buf)[k]);
w2(4);
break;
}
}
/* these macros access the EPAT registers in native addressing */
#define WR(r,v) epat_write_regr(pi,2,r,v)
#define RR(r) (epat_read_regr(pi,2,r))
#define WR(r, v) epat_write_regr(pi, 2, r, v)
#define RR(r) epat_read_regr(pi, 2, r)
/* and these access the IDE task file */
#define WRi(r,v) epat_write_regr(pi,0,r,v)
#define RRi(r) (epat_read_regr(pi,0,r))
#define WRi(r, v) epat_write_regr(pi, 0, r, v)
#define RRi(r) epat_read_regr(pi, 0, r)
/* FIXME: the CPP stuff should be fixed to handle multiple EPATs on a chain */
#define CPP(x) w2(4);w0(0x22);w0(0xaa);w0(0x55);w0(0);w0(0xff);\
w0(0x87);w0(0x78);w0(x);w2(4);w2(5);w2(4);w0(0xff);
#define CPP(x) \
do { \
w2(4); w0(0x22); w0(0xaa); \
w0(0x55); w0(0); w0(0xff); \
w0(0x87); w0(0x78); w0(x); \
w2(4); w2(5); w2(4); w0(0xff); \
} while (0)
static void epat_connect(struct pi_adapter *pi)
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
{
pi->saved_r0 = r0();
pi->saved_r2 = r2();
/* Initialize the chip */
CPP(0);
if (epatc8) {
CPP(0x40);CPP(0xe0);
w0(0);w2(1);w2(4);
WR(0x8,0x12);WR(0xc,0x14);WR(0x12,0x10);
WR(0xe,0xf);WR(0xf,4);
CPP(0x40); CPP(0xe0);
w0(0); w2(1); w2(4);
WR(0x8, 0x12);
WR(0xc, 0x14);
WR(0x12, 0x10);
WR(0xe, 0xf);
WR(0xf, 4);
/* WR(0xe,0xa);WR(0xf,4); */
WR(0xe,0xd);WR(0xf,0);
WR(0xe, 0xd);
WR(0xf, 0);
/* CPP(0x30); */
}
/* Connect to the chip */
CPP(0xe0);
w0(0);w2(1);w2(4); /* Idle into SPP */
w0(0); w2(1); w2(4); /* Idle into SPP */
if (pi->mode >= 3) {
w0(0);w2(1);w2(4);w2(0xc);
/* Request EPP */
w0(0x40);w2(6);w2(7);w2(4);w2(0xc);w2(4);
w0(0); w2(1); w2(4); w2(0xc);
/* Request EPP */
w0(0x40); w2(6); w2(7); w2(4); w2(0xc); w2(4);
}
if (!epatc8) {
WR(8,0x10); WR(0xc,0x14); WR(0xa,0x38); WR(0x12,0x10);
WR(8, 0x10);
WR(0xc, 0x14);
WR(0xa, 0x38);
WR(0x12, 0x10);
}
}
static void epat_disconnect(struct pi_adapter *pi)
{ CPP(0x30);
{
CPP(0x30);
w0(pi->saved_r0);
w2(pi->saved_r2);
}
static int epat_test_proto(struct pi_adapter *pi)
{ int k, j, f, cc;
int e[2] = {0,0};
{
int k, j, f, cc;
int e[2] = { 0, 0 };
char scratch[512];
epat_connect(pi);
epat_connect(pi);
cc = RR(0xd);
epat_disconnect(pi);
epat_connect(pi);
for (j=0;j<2;j++) {
WRi(6,0xa0+j*0x10);
for (k=0;k<256;k++) {
WRi(2,k^0xaa);
WRi(3,k^0x55);
if (RRi(2) != (k^0xaa)) e[j]++;
}
}
epat_disconnect(pi);
WRi(6, 0xa0 + j * 0x10);
for (k = 0; k < 256; k++) {
WRi(2, k ^ 0xaa);
WRi(3, k ^ 0x55);
if (RRi(2) != (k ^ 0xaa))
e[j]++;
}
}
epat_disconnect(pi);
f = 0;
epat_connect(pi);
WR(0x13,1); WR(0x13,0); WR(0xa,0x11);
epat_read_block(pi,scratch,512);
for (k=0;k<256;k++) {
if ((scratch[2*k] & 0xff) != k) f++;
if ((scratch[2*k+1] & 0xff) != (0xff-k)) f++;
}
epat_disconnect(pi);
f = 0;
epat_connect(pi);
WR(0x13, 1); WR(0x13, 0); WR(0xa, 0x11);
epat_read_block(pi, scratch, 512);
dev_dbg(&pi->dev, "epat: port 0x%x, mode %d, ccr %x, test=(%d,%d,%d)\n",
pi->port, pi->mode, cc, e[0], e[1], f);
return (e[0] && e[1]) || f;
for (k = 0; k < 256; k++) {
if ((scratch[2 * k] & 0xff) != k)
f++;
if ((scratch[2 * k + 1] & 0xff) != 0xff - k)
f++;
}
epat_disconnect(pi);
dev_dbg(&pi->dev,
"epat: port 0x%x, mode %d, ccr %x, test=(%d,%d,%d)\n",
pi->port, pi->mode, cc, e[0], e[1], f);
return (e[0] && e[1]) || f;
}
static void epat_log_adapter(struct pi_adapter *pi)
{ int ver;
char *mode_string[6] =
{"4-bit","5/3","8-bit","EPP-8","EPP-16","EPP-32"};
{
int ver;
char *mode_string[6] =
{ "4-bit", "5/3", "8-bit", "EPP-8", "EPP-16", "EPP-32" };
epat_connect(pi);
WR(0xa,0x38); /* read the version code */
ver = RR(0xb);
epat_disconnect(pi);
WR(0xa, 0x38); /* read the version code */
ver = RR(0xb);
epat_disconnect(pi);
dev_info(&pi->dev, "Shuttle EPAT chip %x at 0x%x, mode %d (%s), delay %d\n",
dev_info(&pi->dev,
"Shuttle EPAT chip %x at 0x%x, mode %d (%s), delay %d\n",
ver, pi->port, pi->mode, mode_string[pi->mode], pi->delay);
}

View File

@ -1,14 +1,13 @@
/*
epia.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU General Public License.
epia.c is a low-level protocol driver for Shuttle Technologies
EPIA parallel to IDE adapter chip. This device is now obsolete
and has been replaced with the EPAT chip, which is supported
by epat.c, however, some devices based on EPIA are still
available.
*/
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 1997-1998 Grant R. Guenther <grant@torque.net>
*
* epia.c is a low-level protocol driver for Shuttle Technologies
* EPIA parallel to IDE adapter chip. This device is now obsolete
* and has been replaced with the EPAT chip, which is supported
* by epat.c, however, some devices based on EPIA are still
* available.
*/
#include <linux/module.h>
#include <linux/init.h>
@ -19,255 +18,274 @@
#include <asm/io.h>
#include "pata_parport.h"
/* mode codes: 0 nybble reads on port 1, 8-bit writes
1 5/3 reads on ports 1 & 2, 8-bit writes
2 8-bit reads and writes
3 8-bit EPP mode
4 16-bit EPP
5 32-bit EPP
*/
/*
* mode codes: 0 nybble reads on port 1, 8-bit writes
* 1 5/3 reads on ports 1 & 2, 8-bit writes
* 2 8-bit reads and writes
* 3 8-bit EPP mode
* 4 16-bit EPP
* 5 32-bit EPP
*/
#define j44(a,b) (((a>>4)&0x0f)+(b&0xf0))
#define j53(a,b) (((a>>3)&0x1f)+((b<<4)&0xe0))
/* cont = 0 IDE register file
cont = 1 IDE control registers
*/
#define j44(a, b) (((a >> 4) & 0x0f) + (b & 0xf0))
#define j53(a, b) (((a >> 3) & 0x1f) + ((b << 4) & 0xe0))
/*
* cont = 0 IDE register file
* cont = 1 IDE control registers
*/
static int cont_map[2] = { 0, 0x80 };
static int epia_read_regr(struct pi_adapter *pi, int cont, int regr)
{ int a, b, r;
{
int a, b, r;
regr += cont_map[cont];
switch (pi->mode) {
case 0: r = regr^0x39;
w0(r); w2(1); w2(3); w0(r);
a = r1(); w2(1); b = r1(); w2(4);
return j44(a,b);
case 1: r = regr^0x31;
w0(r); w2(1); w0(r&0x37);
w2(3); w2(5); w0(r|0xf0);
a = r1(); b = r2(); w2(4);
return j53(a,b);
case 2: r = regr^0x29;
w0(r); w2(1); w2(0X21); w2(0x23);
a = r0(); w2(4);
return a;
switch (pi->mode) {
case 0:
r = regr ^ 0x39;
w0(r); w2(1); w2(3); w0(r);
a = r1(); w2(1); b = r1(); w2(4);
return j44(a, b);
case 1:
r = regr ^ 0x31;
w0(r); w2(1); w0(r & 0x37);
w2(3); w2(5); w0(r | 0xf0);
a = r1(); b = r2(); w2(4);
return j53(a, b);
case 2:
r = regr^0x29;
w0(r); w2(1); w2(0X21); w2(0x23);
a = r0(); w2(4);
return a;
case 3:
case 4:
case 5: w3(regr); w2(0x24); a = r4(); w2(4);
return a;
case 5:
w3(regr); w2(0x24); a = r4(); w2(4);
return a;
}
}
return -1;
}
static void epia_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{ int r;
regr += cont_map[cont];
switch (pi->mode) {
case 0:
case 1:
case 2: r = regr^0x19;
w0(r); w2(1); w0(val); w2(3); w2(4);
break;
case 3:
case 4:
case 5: r = regr^0x40;
w3(r); w4(val); w2(4);
break;
}
return -1;
}
#define WR(r,v) epia_write_regr(pi,0,r,v)
#define RR(r) (epia_read_regr(pi,0,r))
static void epia_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{
int r;
/* The use of register 0x84 is entirely unclear - it seems to control
some EPP counters ... currently we know about 3 different block
sizes: the standard 512 byte reads and writes, 12 byte writes and
2048 byte reads (the last two being used in the CDrom drivers.
*/
regr += cont_map[cont];
switch (pi->mode) {
case 0:
case 1:
case 2:
r = regr ^ 0x19;
w0(r); w2(1); w0(val); w2(3); w2(4);
break;
case 3:
case 4:
case 5:
r = regr ^ 0x40;
w3(r); w4(val); w2(4);
break;
}
}
#define WR(r, v) epia_write_regr(pi, 0, r, v)
#define RR(r) epia_read_regr(pi, 0, r)
/*
* The use of register 0x84 is entirely unclear - it seems to control
* some EPP counters ... currently we know about 3 different block
* sizes: the standard 512 byte reads and writes, 12 byte writes and
* 2048 byte reads (the last two being used in the CDrom drivers.
*/
static void epia_connect(struct pi_adapter *pi)
{
pi->saved_r0 = r0();
pi->saved_r2 = r2();
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(4); w0(0xa0); w0(0x50); w0(0xc0); w0(0x30); w0(0xa0); w0(0);
w2(1); w2(4);
if (pi->mode >= 3) {
w0(0xa); w2(1); w2(4); w0(0x82); w2(4); w2(0xc); w2(4);
w2(0x24); w2(0x26); w2(4);
}
WR(0x86,8);
w2(4); w0(0xa0); w0(0x50); w0(0xc0); w0(0x30); w0(0xa0); w0(0);
w2(1); w2(4);
if (pi->mode >= 3) {
w0(0xa); w2(1); w2(4); w0(0x82); w2(4); w2(0xc); w2(4);
w2(0x24); w2(0x26); w2(4);
}
WR(0x86, 8);
}
static void epia_disconnect(struct pi_adapter *pi)
{ /* WR(0x84,0x10); */
w0(pi->saved_r0);
w2(1); w2(4);
w0(pi->saved_r0);
w2(pi->saved_r2);
}
{
/* WR(0x84,0x10); */
w0(pi->saved_r0);
w2(1); w2(4);
w0(pi->saved_r0);
w2(pi->saved_r2);
}
static void epia_read_block(struct pi_adapter *pi, char *buf, int count)
{ int k, ph, a, b;
{
int k, ph, a, b;
switch (pi->mode) {
case 0: w0(0x81); w2(1); w2(3); w0(0xc1);
ph = 1;
for (k=0;k<count;k++) {
w2(2+ph); a = r1();
w2(4+ph); b = r1();
buf[k] = j44(a,b);
ph = 1 - ph;
}
w0(0); w2(4);
break;
case 1: w0(0x91); w2(1); w0(0x10); w2(3);
w0(0x51); w2(5); w0(0xd1);
ph = 1;
for (k=0;k<count;k++) {
w2(4+ph);
a = r1(); b = r2();
buf[k] = j53(a,b);
ph = 1 - ph;
}
w0(0); w2(4);
break;
case 2: w0(0x89); w2(1); w2(0x23); w2(0x21);
ph = 1;
for (k=0;k<count;k++) {
w2(0x24+ph);
buf[k] = r0();
ph = 1 - ph;
}
w2(6); w2(4);
break;
case 3: if (count > 512) WR(0x84,3);
switch (pi->mode) {
case 0:
w0(0x81); w2(1); w2(3); w0(0xc1);
ph = 1;
for (k = 0; k < count; k++) {
w2(2+ph); a = r1();
w2(4+ph); b = r1();
buf[k] = j44(a, b);
ph = 1 - ph;
}
w0(0); w2(4);
break;
case 1:
w0(0x91); w2(1); w0(0x10); w2(3);
w0(0x51); w2(5); w0(0xd1);
ph = 1;
for (k = 0; k < count; k++) {
w2(4 + ph);
a = r1(); b = r2();
buf[k] = j53(a, b);
ph = 1 - ph;
}
w0(0); w2(4);
break;
case 2:
w0(0x89); w2(1); w2(0x23); w2(0x21);
ph = 1;
for (k = 0; k < count; k++) {
w2(0x24 + ph);
buf[k] = r0();
ph = 1 - ph;
}
w2(6); w2(4);
break;
case 3:
if (count > 512)
WR(0x84, 3);
w3(0); w2(0x24);
for (k=0;k<count;k++) buf[k] = r4();
w2(4); WR(0x84,0);
break;
case 4: if (count > 512) WR(0x84,3);
for (k = 0; k < count; k++)
buf[k] = r4();
w2(4); WR(0x84, 0);
break;
case 4:
if (count > 512)
WR(0x84, 3);
w3(0); w2(0x24);
for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
w2(4); WR(0x84,0);
break;
case 5: if (count > 512) WR(0x84,3);
for (k = 0; k < count / 2; k++)
((u16 *)buf)[k] = r4w();
w2(4); WR(0x84, 0);
break;
case 5:
if (count > 512)
WR(0x84, 3);
w3(0); w2(0x24);
for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
w2(4); WR(0x84,0);
break;
}
for (k = 0; k < count / 4; k++)
((u32 *)buf)[k] = r4l();
w2(4); WR(0x84, 0);
break;
}
}
static void epia_write_block(struct pi_adapter *pi, char *buf, int count)
{
int ph, k, last, d;
{ int ph, k, last, d;
switch (pi->mode) {
case 0:
case 1:
case 2: w0(0xa1); w2(1); w2(3); w2(1); w2(5);
ph = 0; last = 0x8000;
for (k=0;k<count;k++) {
d = buf[k];
if (d != last) { last = d; w0(d); }
w2(4+ph);
ph = 1 - ph;
}
w2(7); w2(4);
break;
case 3: if (count < 512) WR(0x84,1);
switch (pi->mode) {
case 0:
case 1:
case 2:
w0(0xa1); w2(1); w2(3); w2(1); w2(5);
ph = 0; last = 0x8000;
for (k = 0; k < count; k++) {
d = buf[k];
if (d != last) {
last = d;
w0(d);
}
w2(4 + ph);
ph = 1 - ph;
}
w2(7); w2(4);
break;
case 3:
if (count < 512)
WR(0x84, 1);
w3(0x40);
for (k=0;k<count;k++) w4(buf[k]);
if (count < 512) WR(0x84,0);
break;
case 4: if (count < 512) WR(0x84,1);
for (k = 0; k < count; k++)
w4(buf[k]);
if (count < 512)
WR(0x84, 0);
break;
case 4:
if (count < 512)
WR(0x84, 1);
w3(0x40);
for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
if (count < 512) WR(0x84,0);
break;
case 5: if (count < 512) WR(0x84,1);
for (k = 0; k < count / 2; k++)
w4w(((u16 *)buf)[k]);
if (count < 512)
WR(0x84, 0);
break;
case 5:
if (count < 512)
WR(0x84, 1);
w3(0x40);
for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
if (count < 512) WR(0x84,0);
break;
}
for (k = 0; k < count / 4; k++)
w4l(((u32 *)buf)[k]);
if (count < 512)
WR(0x84, 0);
break;
}
}
static int epia_test_proto(struct pi_adapter *pi)
{ int j, k, f;
int e[2] = {0,0};
{
int j, k, f;
int e[2] = { 0, 0 };
char scratch[512];
epia_connect(pi);
for (j=0;j<2;j++) {
WR(6,0xa0+j*0x10);
for (k=0;k<256;k++) {
WR(2,k^0xaa);
WR(3,k^0x55);
if (RR(2) != (k^0xaa)) e[j]++;
}
WR(2,1); WR(3,1);
}
epia_disconnect(pi);
epia_connect(pi);
for (j = 0; j < 2; j++) {
WR(6, 0xa0 + j * 0x10);
for (k = 0; k < 256; k++) {
WR(2, k ^ 0xaa);
WR(3, k ^ 0x55);
if (RR(2) != (k ^ 0xaa))
e[j]++;
}
WR(2, 1); WR(3, 1);
}
epia_disconnect(pi);
f = 0;
epia_connect(pi);
WR(0x84,8);
epia_read_block(pi,scratch,512);
for (k=0;k<256;k++) {
if ((scratch[2*k] & 0xff) != ((k+1) & 0xff)) f++;
if ((scratch[2*k+1] & 0xff) != ((-2-k) & 0xff)) f++;
}
WR(0x84,0);
epia_disconnect(pi);
f = 0;
epia_connect(pi);
WR(0x84, 8);
epia_read_block(pi, scratch, 512);
for (k = 0; k < 256; k++) {
if ((scratch[2 * k] & 0xff) != ((k + 1) & 0xff))
f++;
if ((scratch[2 * k + 1] & 0xff) != ((-2 - k) & 0xff))
f++;
}
WR(0x84, 0);
epia_disconnect(pi);
dev_dbg(&pi->dev, "epia: port 0x%x, mode %d, test=(%d,%d,%d)\n",
pi->port, pi->mode, e[0], e[1], f);
return (e[0] && e[1]) || f;
pi->port, pi->mode, e[0], e[1], f);
return (e[0] && e[1]) || f;
}
static void epia_log_adapter(struct pi_adapter *pi)
{
char *mode[6] = { "4-bit", "5/3", "8-bit", "EPP-8", "EPP-16", "EPP-32"};
{ char *mode_string[6] = {"4-bit","5/3","8-bit",
"EPP-8","EPP-16","EPP-32"};
dev_info(&pi->dev, "Shuttle EPIA at 0x%x, mode %d (%s), delay %d\n",
pi->port, pi->mode, mode_string[pi->mode], pi->delay);
dev_info(&pi->dev,
"Shuttle EPIA at 0x%x, mode %d (%s), delay %d\n",
pi->port, pi->mode, mode[pi->mode], pi->delay);
}
static struct pi_protocol epia = {

View File

@ -1,17 +1,16 @@
/*
fit2.c (c) 1998 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU General Public License.
fit2.c is a low-level protocol driver for the older version
of the Fidelity International Technology parallel port adapter.
This adapter is used in their TransDisk 2000 and older TransDisk
3000 portable hard-drives. As far as I can tell, this device
supports 4-bit mode _only_.
Newer models of the FIT products use an enhanced protocol.
The "fit3" protocol module should support current drives.
*/
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 1998 Grant R. Guenther <grant@torque.net>
*
* fit2.c is a low-level protocol driver for the older version
* of the Fidelity International Technology parallel port adapter.
* This adapter is used in their TransDisk 2000 and older TransDisk
* 3000 portable hard-drives. As far as I can tell, this device
* supports 4-bit mode _only_.
*
* Newer models of the FIT products use an enhanced protocol.
* The "fit3" protocol module should support current drives.
*/
#include <linux/module.h>
#include <linux/init.h>
@ -22,99 +21,97 @@
#include <asm/io.h>
#include "pata_parport.h"
#define j44(a,b) (((a>>4)&0x0f)|(b&0xf0))
#define j44(a, b) (((a >> 4) & 0x0f) | (b & 0xf0))
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
NB: The FIT adapter does not appear to use the control registers.
So, we map ALT_STATUS to STATUS and NO-OP writes to the device
control register - this means that IDE reset will not work on these
devices.
*/
/*
* cont = 0 - access the IDE register file
* cont = 1 - access the IDE command set
*
* NB: The FIT adapter does not appear to use the control registers.
* So, we map ALT_STATUS to STATUS and NO-OP writes to the device
* control register - this means that IDE reset will not work on these
* devices.
*/
static void fit2_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{ if (cont == 1) return;
{
if (cont == 1)
return;
w2(0xc); w0(regr); w2(4); w0(val); w2(5); w0(0); w2(4);
}
static int fit2_read_regr(struct pi_adapter *pi, int cont, int regr)
{ int a, b, r;
{
int a, b, r;
if (cont) {
if (regr != 6) return 0xff;
r = 7;
} else r = regr + 0x10;
if (regr != 6)
return 0xff;
r = 7;
} else {
r = regr + 0x10;
}
w2(0xc); w0(r); w2(4); w2(5);
w0(0); a = r1();
w0(1); b = r1();
w2(0xc); w0(r); w2(4); w2(5);
w0(0); a = r1();
w0(1); b = r1();
w2(4);
return j44(a,b);
return j44(a, b);
}
static void fit2_read_block(struct pi_adapter *pi, char *buf, int count)
{ int k, a, b, c, d;
{
int k, a, b, c, d;
w2(0xc); w0(0x10);
for (k=0;k<count/4;k++) {
for (k = 0; k < count / 4; k++) {
w2(4); w2(5);
w0(0); a = r1(); w0(1); b = r1();
w0(3); c = r1(); w0(2); d = r1();
buf[4*k+0] = j44(a,b);
buf[4*k+1] = j44(d,c);
w2(4); w2(5);
a = r1(); w0(3); b = r1();
w0(1); c = r1(); w0(0); d = r1();
buf[4*k+2] = j44(d,c);
buf[4*k+3] = j44(a,b);
w0(3); c = r1(); w0(2); d = r1();
buf[4 * k + 0] = j44(a, b);
buf[4 * k + 1] = j44(d, c);
w2(4); w2(5);
a = r1(); w0(3); b = r1();
w0(1); c = r1(); w0(0); d = r1();
buf[4 * k + 2] = j44(d, c);
buf[4 * k + 3] = j44(a, b);
}
w2(4);
}
static void fit2_write_block(struct pi_adapter *pi, char *buf, int count)
{
int k;
{ int k;
w2(0xc); w0(0);
for (k=0;k<count/2;k++) {
w2(4); w0(buf[2*k]);
w2(5); w0(buf[2*k+1]);
w2(0xc); w0(0);
for (k = 0; k < count / 2; k++) {
w2(4); w0(buf[2 * k]);
w2(5); w0(buf[2 * k + 1]);
}
w2(4);
}
static void fit2_connect(struct pi_adapter *pi)
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(0xcc);
{
pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(0xcc);
}
static void fit2_disconnect(struct pi_adapter *pi)
{ w0(pi->saved_r0);
w2(pi->saved_r2);
}
{
w0(pi->saved_r0);
w2(pi->saved_r2);
}
static void fit2_log_adapter(struct pi_adapter *pi)
{
dev_info(&pi->dev, "FIT 2000 adapter at 0x%x, delay %d\n",
pi->port, pi->delay);
pi->port, pi->delay);
}

View File

@ -1,21 +1,20 @@
/*
fit3.c (c) 1998 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU General Public License.
fit3.c is a low-level protocol driver for newer models
of the Fidelity International Technology parallel port adapter.
This adapter is used in their TransDisk 3000 portable
hard-drives, as well as CD-ROM, PD-CD and other devices.
The TD-2000 and certain older devices use a different protocol.
Try the fit2 protocol module with them.
NB: The FIT adapters do not appear to support the control
registers. So, we map ALT_STATUS to STATUS and NO-OP writes
to the device control register - this means that IDE reset
will not work on these devices.
*/
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 1998 Grant R. Guenther <grant@torque.net>
*
* fit3.c is a low-level protocol driver for newer models
* of the Fidelity International Technology parallel port adapter.
* This adapter is used in their TransDisk 3000 portable
* hard-drives, as well as CD-ROM, PD-CD and other devices.
*
* The TD-2000 and certain older devices use a different protocol.
* Try the fit2 protocol module with them.
*
* NB: The FIT adapters do not appear to support the control
* registers. So, we map ALT_STATUS to STATUS and NO-OP writes
* to the device control register - this means that IDE reset
* will not work on these devices.
*/
#include <linux/module.h>
#include <linux/init.h>
@ -26,152 +25,155 @@
#include <asm/io.h>
#include "pata_parport.h"
#define j44(a,b) (((a>>3)&0x0f)|((b<<1)&0xf0))
#define j44(a, b) (((a >> 3) & 0x0f) | ((b << 1) & 0xf0))
#define w7(byte) {out_p(7,byte);}
#define r7() (in_p(7) & 0xff)
#define w7(byte) out_p(7, byte)
#define r7() (in_p(7) & 0xff)
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
*/
/*
* cont = 0 - access the IDE register file
* cont = 1 - access the IDE command set
*/
static void fit3_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{ if (cont == 1) return;
{
if (cont == 1)
return;
switch (pi->mode) {
case 0:
case 1: w2(0xc); w0(regr); w2(0x8); w2(0xc);
w0(val); w2(0xd);
case 1:
w2(0xc); w0(regr); w2(0x8); w2(0xc);
w0(val); w2(0xd);
w0(0); w2(0xc);
break;
case 2: w2(0xc); w0(regr); w2(0x8); w2(0xc);
case 2:
w2(0xc); w0(regr); w2(0x8); w2(0xc);
w4(val); w4(0);
w2(0xc);
break;
}
}
static int fit3_read_regr(struct pi_adapter *pi, int cont, int regr)
{ int a, b;
{
int a, b;
if (cont) {
if (regr != 6) return 0xff;
regr = 7;
}
if (regr != 6)
return 0xff;
regr = 7;
}
switch (pi->mode) {
case 0: w2(0xc); w0(regr + 0x10); w2(0x8); w2(0xc);
case 0:
w2(0xc); w0(regr + 0x10); w2(0x8); w2(0xc);
w2(0xd); a = r1();
w2(0xf); b = r1();
w2(0xf); b = r1();
w2(0xc);
return j44(a,b);
case 1: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc);
w2(0xec); w2(0xee); w2(0xef); a = r0();
return j44(a, b);
case 1:
w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc);
w2(0xec); w2(0xee); w2(0xef); a = r0();
w2(0xc);
return a;
case 2: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc);
w2(0xec);
a = r4(); b = r4();
case 2:
w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc);
w2(0xec);
a = r4(); b = r4();
w2(0xc);
return a;
}
return -1;
return -1;
}
static void fit3_read_block(struct pi_adapter *pi, char *buf, int count)
{ int k, a, b, c, d;
{
int k, a, b, c, d;
switch (pi->mode) {
case 0: w2(0xc); w0(0x10); w2(0x8); w2(0xc);
for (k=0;k<count/2;k++) {
w2(0xd); a = r1();
w2(0xf); b = r1();
w2(0xc); c = r1();
w2(0xe); d = r1();
buf[2*k ] = j44(a,b);
buf[2*k+1] = j44(c,d);
case 0:
w2(0xc); w0(0x10); w2(0x8); w2(0xc);
for (k = 0; k < count / 2; k++) {
w2(0xd); a = r1();
w2(0xf); b = r1();
w2(0xc); c = r1();
w2(0xe); d = r1();
buf[2 * k] = j44(a, b);
buf[2 * k + 1] = j44(c, d);
}
w2(0xc);
break;
case 1: w2(0xc); w0(0x90); w2(0x8); w2(0xc);
case 1:
w2(0xc); w0(0x90); w2(0x8); w2(0xc);
w2(0xec); w2(0xee);
for (k=0;k<count/2;k++) {
w2(0xef); a = r0();
w2(0xee); b = r0();
buf[2*k ] = a;
buf[2*k+1] = b;
for (k = 0; k < count / 2; k++) {
w2(0xef); a = r0();
w2(0xee); b = r0();
buf[2 * k] = a;
buf[2 * k + 1] = b;
}
w2(0xec);
w2(0xec);
w2(0xc);
break;
case 2: w2(0xc); w0(0x90); w2(0x8); w2(0xc);
w2(0xec);
for (k=0;k<count;k++) buf[k] = r4();
w2(0xc);
case 2:
w2(0xc); w0(0x90); w2(0x8); w2(0xc);
w2(0xec);
for (k = 0; k < count; k++)
buf[k] = r4();
w2(0xc);
break;
}
}
static void fit3_write_block(struct pi_adapter *pi, char *buf, int count)
{
int k;
{ int k;
switch (pi->mode) {
switch (pi->mode) {
case 0:
case 1: w2(0xc); w0(0); w2(0x8); w2(0xc);
for (k=0;k<count/2;k++) {
w0(buf[2*k ]); w2(0xd);
w0(buf[2*k+1]); w2(0xc);
case 1:
w2(0xc); w0(0); w2(0x8); w2(0xc);
for (k = 0; k < count / 2; k++) {
w0(buf[2 * k]); w2(0xd);
w0(buf[2 * k + 1]); w2(0xc);
}
break;
case 2: w2(0xc); w0(0); w2(0x8); w2(0xc);
for (k=0;k<count;k++) w4(buf[k]);
w2(0xc);
case 2:
w2(0xc); w0(0); w2(0x8); w2(0xc);
for (k = 0; k < count; k++)
w4(buf[k]);
w2(0xc);
break;
}
}
static void fit3_connect(struct pi_adapter *pi)
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
{
pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(0xc); w0(0); w2(0xa);
if (pi->mode == 2) {
w2(0xc); w0(0x9); w2(0x8); w2(0xc);
}
if (pi->mode == 2) {
w2(0xc); w0(0x9);
w2(0x8); w2(0xc);
}
}
static void fit3_disconnect(struct pi_adapter *pi)
{ w2(0xc); w0(0xa); w2(0x8); w2(0xc);
{
w2(0xc); w0(0xa); w2(0x8); w2(0xc);
w0(pi->saved_r0);
w2(pi->saved_r2);
}
w2(pi->saved_r2);
}
static void fit3_log_adapter(struct pi_adapter *pi)
{
char *mode_string[3] = { "4-bit", "8-bit", "EPP"};
{ char *mode_string[3] = {"4-bit","8-bit","EPP"};
dev_info(&pi->dev, "FIT 3000 adapter at 0x%x, mode %d (%s), delay %d\n",
pi->port, pi->mode, mode_string[pi->mode], pi->delay);
dev_info(&pi->dev,
"FIT 3000 adapter at 0x%x, mode %d (%s), delay %d\n",
pi->port, pi->mode, mode_string[pi->mode], pi->delay);
}
static struct pi_protocol fit3 = {

View File

@ -1,24 +1,23 @@
/*
friq.c (c) 1998 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU General Public License
friq.c is a low-level protocol driver for the Freecom "IQ"
parallel port IDE adapter. Early versions of this adapter
use the 'frpw' protocol.
Freecom uses this adapter in a battery powered external
CD-ROM drive. It is also used in LS-120 drives by
Maxell and Panasonic, and other devices.
The battery powered drive requires software support to
control the power to the drive. This module enables the
drive power when the high level driver (pcd) is loaded
and disables it when the module is unloaded. Note, if
the friq module is built in to the kernel, the power
will never be switched off, so other means should be
used to conserve battery power.
*/
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 1998 Grant R. Guenther <grant@torque.net>
*
* friq.c is a low-level protocol driver for the Freecom "IQ"
* parallel port IDE adapter. Early versions of this adapter
* use the 'frpw' protocol.
*
* Freecom uses this adapter in a battery powered external
* CD-ROM drive. It is also used in LS-120 drives by
* Maxell and Panasonic, and other devices.
*
* The battery powered drive requires software support to
* control the power to the drive. This module enables the
* drive power when the high level driver (pcd) is loaded
* and disables it when the module is unloaded. Note, if
* the friq module is built in to the kernel, the power
* will never be switched off, so other means should be
* used to conserve battery power.
*/
#include <linux/module.h>
#include <linux/init.h>
@ -29,197 +28,206 @@
#include <asm/io.h>
#include "pata_parport.h"
#define CMD(x) w2(4);w0(0xff);w0(0xff);w0(0x73);w0(0x73);\
w0(0xc9);w0(0xc9);w0(0x26);w0(0x26);w0(x);w0(x);
#define CMD(x) \
do { \
w2(4); w0(0xff); w0(0xff); w0(0x73); w0(0x73); \
w0(0xc9); w0(0xc9); w0(0x26); \
w0(0x26); w0(x); w0(x); \
} while (0)
#define j44(l,h) (((l>>4)&0x0f)|(h&0xf0))
#define j44(l, h) (((l >> 4) & 0x0f) | (h & 0xf0))
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
*/
static int cont_map[2] = { 0x08, 0x10 };
/*
* cont = 0 - access the IDE register file
* cont = 1 - access the IDE command set
*/
static int cont_map[2] = { 0x08, 0x10 };
static int friq_read_regr(struct pi_adapter *pi, int cont, int regr)
{ int h,l,r;
{
int h, l, r;
r = regr + cont_map[cont];
CMD(r);
w2(6); l = r1();
w2(4); h = r1();
w2(4);
return j44(l,h);
w2(4);
return j44(l, h);
}
static void friq_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{ int r;
r = regr + cont_map[cont];
{
int r = regr + cont_map[cont];
CMD(r);
w0(val);
w2(5);w2(7);w2(5);w2(4);
w2(5); w2(7); w2(5); w2(4);
}
static void friq_read_block_int(struct pi_adapter *pi, char *buf, int count, int regr)
{
int h, l, k, ph;
{ int h, l, k, ph;
switch(pi->mode) {
case 0: CMD(regr);
for (k=0;k<count;k++) {
w2(6); l = r1();
w2(4); h = r1();
buf[k] = j44(l,h);
}
w2(4);
break;
case 1: ph = 2;
CMD(regr+0xc0);
w0(0xff);
for (k=0;k<count;k++) {
w2(0xa4 + ph);
buf[k] = r0();
ph = 2 - ph;
}
w2(0xac); w2(0xa4); w2(4);
break;
case 2: CMD(regr+0x80);
for (k=0;k<count-2;k++) buf[k] = r4();
w2(0xac); w2(0xa4);
buf[count-2] = r4();
buf[count-1] = r4();
w2(4);
break;
case 3: CMD(regr+0x80);
for (k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
w2(0xac); w2(0xa4);
buf[count-2] = r4();
buf[count-1] = r4();
w2(4);
break;
case 4: CMD(regr+0x80);
for (k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
buf[count-4] = r4();
buf[count-3] = r4();
w2(0xac); w2(0xa4);
buf[count-2] = r4();
buf[count-1] = r4();
w2(4);
break;
}
}
static void friq_read_block(struct pi_adapter *pi, char *buf, int count)
{ friq_read_block_int(pi,buf,count,0x08);
}
static void friq_write_block(struct pi_adapter *pi, char *buf, int count)
{ int k;
switch(pi->mode) {
switch (pi->mode) {
case 0:
case 1: CMD(8); w2(5);
for (k=0;k<count;k++) {
w0(buf[k]);
w2(7);w2(5);
CMD(regr);
for (k = 0; k < count; k++) {
w2(6); l = r1();
w2(4); h = r1();
buf[k] = j44(l, h);
}
w2(4);
break;
case 2: CMD(0xc8); w2(5);
for (k=0;k<count;k++) w4(buf[k]);
case 1:
ph = 2;
CMD(regr + 0xc0);
w0(0xff);
for (k = 0; k < count; k++) {
w2(0xa4 + ph);
buf[k] = r0();
ph = 2 - ph;
}
w2(0xac); w2(0xa4); w2(4);
break;
case 2:
CMD(regr + 0x80);
for (k = 0; k < count - 2; k++)
buf[k] = r4();
w2(0xac); w2(0xa4);
buf[count - 2] = r4();
buf[count - 1] = r4();
w2(4);
break;
case 3:
CMD(regr + 0x80);
for (k = 0; k < count / 2 - 1; k++)
((u16 *)buf)[k] = r4w();
w2(0xac); w2(0xa4);
buf[count - 2] = r4();
buf[count - 1] = r4();
w2(4);
break;
case 4:
CMD(regr + 0x80);
for (k = 0; k < count / 4 - 1; k++)
((u32 *)buf)[k] = r4l();
buf[count - 4] = r4();
buf[count - 3] = r4();
w2(0xac); w2(0xa4);
buf[count - 2] = r4();
buf[count - 1] = r4();
w2(4);
break;
case 3: CMD(0xc8); w2(5);
for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
w2(4);
break;
case 4: CMD(0xc8); w2(5);
for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
w2(4);
break;
}
}
static void friq_connect(struct pi_adapter *pi)
static void friq_read_block(struct pi_adapter *pi, char *buf, int count)
{
friq_read_block_int(pi, buf, count, 0x08);
}
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
static void friq_write_block(struct pi_adapter *pi, char *buf, int count)
{
int k;
switch (pi->mode) {
case 0:
case 1:
CMD(8); w2(5);
for (k = 0; k < count; k++) {
w0(buf[k]);
w2(7); w2(5);
}
w2(4);
break;
case 2:
CMD(0xc8); w2(5);
for (k = 0; k < count; k++)
w4(buf[k]);
w2(4);
break;
case 3:
CMD(0xc8); w2(5);
for (k = 0; k < count / 2; k++)
w4w(((u16 *)buf)[k]);
w2(4);
break;
case 4:
CMD(0xc8); w2(5);
for (k = 0; k < count / 4; k++)
w4l(((u32 *)buf)[k]);
w2(4);
break;
}
}
static void friq_connect(struct pi_adapter *pi)
{
pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(4);
}
static void friq_disconnect(struct pi_adapter *pi)
{ CMD(0x20);
{
CMD(0x20);
w0(pi->saved_r0);
w2(pi->saved_r2);
}
w2(pi->saved_r2);
}
static int friq_test_proto(struct pi_adapter *pi)
{ int j, k, r;
int e[2] = {0,0};
{
int j, k, r;
int e[2] = { 0, 0 };
char scratch[512];
pi->saved_r0 = r0();
pi->saved_r0 = r0();
w0(0xff); udelay(20); CMD(0x3d); /* turn the power on */
udelay(500);
w0(pi->saved_r0);
friq_connect(pi);
for (j=0;j<2;j++) {
friq_write_regr(pi,0,6,0xa0+j*0x10);
for (k=0;k<256;k++) {
friq_write_regr(pi,0,2,k^0xaa);
friq_write_regr(pi,0,3,k^0x55);
if (friq_read_regr(pi,0,2) != (k^0xaa)) e[j]++;
}
}
for (j = 0; j < 2; j++) {
friq_write_regr(pi, 0, 6, 0xa0 + j * 0x10);
for (k = 0; k < 256; k++) {
friq_write_regr(pi, 0, 2, k ^ 0xaa);
friq_write_regr(pi, 0, 3, k ^ 0x55);
if (friq_read_regr(pi, 0, 2) != (k ^ 0xaa))
e[j]++;
}
}
friq_disconnect(pi);
friq_connect(pi);
friq_read_block_int(pi,scratch,512,0x10);
r = 0;
for (k=0;k<128;k++) if (scratch[k] != k) r++;
friq_read_block_int(pi, scratch, 512, 0x10);
r = 0;
for (k = 0; k < 128; k++) {
if (scratch[k] != k)
r++;
}
friq_disconnect(pi);
dev_dbg(&pi->dev, "friq: port 0x%x, mode %d, test=(%d,%d,%d)\n",
pi->port, pi->mode, e[0], e[1], r);
dev_dbg(&pi->dev,
"friq: port 0x%x, mode %d, test=(%d,%d,%d)\n",
pi->port, pi->mode, e[0], e[1], r);
return (r || (e[0] && e[1]));
return r || (e[0] && e[1]);
}
static void friq_log_adapter(struct pi_adapter *pi)
{
char *mode_string[6] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32"};
{ char *mode_string[6] = {"4-bit","8-bit",
"EPP-8","EPP-16","EPP-32"};
dev_info(&pi->dev, "Freecom IQ ASIC-2 adapter at 0x%x, mode %d (%s), delay %d\n",
pi->port, pi->mode, mode_string[pi->mode], pi->delay);
dev_info(&pi->dev,
"Freecom IQ ASIC-2 adapter at 0x%x, mode %d (%s), delay %d\n",
pi->port, pi->mode, mode_string[pi->mode], pi->delay);
pi->private = 1;
friq_connect(pi);
CMD(0x9e); /* disable sleep timer */
friq_disconnect(pi);
}
static void friq_release_proto(struct pi_adapter *pi)

View File

@ -1,17 +1,15 @@
/*
frpw.c (c) 1996-8 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU General Public License
frpw.c is a low-level protocol driver for the Freecom "Power"
parallel port IDE adapter.
Some applications of this adapter may require a "printer" reset
prior to loading the driver. This can be done by loading and
unloading the "lp" driver, or it can be done by this driver
if you define FRPW_HARD_RESET. The latter is not recommended
as it may upset devices on other ports.
*/
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 1996-1998 Grant R. Guenther <grant@torque.net>
*
* frpw.c is a low-level protocol driver for the Freecom "Power" parallel port
* IDE adapter.
*
* Some applications of this adapter may require a "printer" reset prior to
* loading the driver. This can be done by loading and unloading the "lp"
* driver, or it can be done by this driver if you define FRPW_HARD_RESET.
* The latter is not recommended as it may upset devices on other ports.
*/
#include <linux/module.h>
#include <linux/init.h>
@ -25,15 +23,15 @@
#define cec4 w2(0xc);w2(0xe);w2(0xe);w2(0xc);w2(4);w2(4);w2(4);
#define j44(l,h) (((l>>4)&0x0f)|(h&0xf0))
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
*/
/*
* cont = 0 - access the IDE register file
* cont = 1 - access the IDE command set
*/
static int cont_map[2] = { 0x08, 0x10 };
static int frpw_read_regr(struct pi_adapter *pi, int cont, int regr)
{ int h,l,r;
{
int h, l, r;
r = regr + cont_map[cont];
@ -41,145 +39,156 @@ static int frpw_read_regr(struct pi_adapter *pi, int cont, int regr)
w0(r); cec4;
w2(6); l = r1();
w2(4); h = r1();
w2(4);
return j44(l,h);
w2(4);
return j44(l, h);
}
static void frpw_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{
int r = regr + cont_map[cont];
{ int r;
r = regr + cont_map[cont];
w2(4); w0(r); cec4;
w2(4); w0(r); cec4;
w0(val);
w2(5);w2(7);w2(5);w2(4);
w2(5); w2(7); w2(5); w2(4);
}
static void frpw_read_block_int(struct pi_adapter *pi, char *buf, int count, int regr)
{ int h, l, k, ph;
switch(pi->mode) {
case 0: w2(4); w0(regr); cec4;
for (k=0;k<count;k++) {
w2(6); l = r1();
w2(4); h = r1();
buf[k] = j44(l,h);
}
w2(4);
break;
case 1: ph = 2;
w2(4); w0(regr + 0xc0); cec4;
w0(0xff);
for (k=0;k<count;k++) {
w2(0xa4 + ph);
buf[k] = r0();
ph = 2 - ph;
}
w2(0xac); w2(0xa4); w2(4);
break;
case 2: w2(4); w0(regr + 0x80); cec4;
for (k=0;k<count;k++) buf[k] = r4();
w2(0xac); w2(0xa4);
w2(4);
break;
case 3: w2(4); w0(regr + 0x80); cec4;
for (k=0;k<count-2;k++) buf[k] = r4();
w2(0xac); w2(0xa4);
buf[count-2] = r4();
buf[count-1] = r4();
w2(4);
break;
case 4: w2(4); w0(regr + 0x80); cec4;
for (k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
w2(0xac); w2(0xa4);
buf[count-2] = r4();
buf[count-1] = r4();
w2(4);
break;
case 5: w2(4); w0(regr + 0x80); cec4;
for (k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
buf[count-4] = r4();
buf[count-3] = r4();
w2(0xac); w2(0xa4);
buf[count-2] = r4();
buf[count-1] = r4();
w2(4);
break;
}
}
static void frpw_read_block(struct pi_adapter *pi, char *buf, int count)
{ frpw_read_block_int(pi,buf,count,0x08);
}
static void frpw_write_block(struct pi_adapter *pi, char *buf, int count)
{ int k;
switch(pi->mode) {
static void frpw_read_block_int(struct pi_adapter *pi, char *buf, int count,
int regr)
{
int h, l, k, ph;
switch (pi->mode) {
case 0:
case 1:
case 2: w2(4); w0(8); cec4; w2(5);
for (k=0;k<count;k++) {
w0(buf[k]);
w2(7);w2(5);
w2(4); w0(regr); cec4;
for (k = 0; k < count; k++) {
w2(6); l = r1();
w2(4); h = r1();
buf[k] = j44(l, h);
}
w2(4);
break;
case 3: w2(4); w0(0xc8); cec4; w2(5);
for (k=0;k<count;k++) w4(buf[k]);
case 1:
ph = 2;
w2(4); w0(regr + 0xc0); cec4;
w0(0xff);
for (k = 0; k < count; k++) {
w2(0xa4 + ph);
buf[k] = r0();
ph = 2 - ph;
}
w2(0xac); w2(0xa4); w2(4);
break;
case 2:
w2(4); w0(regr + 0x80); cec4;
for (k = 0; k < count; k++)
buf[k] = r4();
w2(0xac); w2(0xa4);
w2(4);
break;
case 4: w2(4); w0(0xc8); cec4; w2(5);
for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
w2(4);
break;
case 3:
w2(4); w0(regr + 0x80); cec4;
for (k = 0; k < count - 2; k++)
buf[k] = r4();
w2(0xac); w2(0xa4);
buf[count - 2] = r4();
buf[count - 1] = r4();
w2(4);
break;
case 5: w2(4); w0(0xc8); cec4; w2(5);
for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
w2(4);
break;
case 4:
w2(4); w0(regr + 0x80); cec4;
for (k = 0; k < count / 2 - 1; k++)
((u16 *)buf)[k] = r4w();
w2(0xac); w2(0xa4);
buf[count - 2] = r4();
buf[count - 1] = r4();
w2(4);
break;
case 5:
w2(4); w0(regr + 0x80); cec4;
for (k = 0; k < count / 4 - 1; k++)
((u32 *)buf)[k] = r4l();
buf[count - 4] = r4();
buf[count - 3] = r4();
w2(0xac); w2(0xa4);
buf[count - 2] = r4();
buf[count - 1] = r4();
w2(4);
break;
}
}
static void frpw_read_block(struct pi_adapter *pi, char *buf, int count)
{
frpw_read_block_int(pi, buf, count, 0x08);
}
static void frpw_write_block(struct pi_adapter *pi, char *buf, int count)
{
int k;
switch (pi->mode) {
case 0:
case 1:
case 2:
w2(4); w0(8); cec4; w2(5);
for (k = 0; k < count; k++) {
w0(buf[k]);
w2(7); w2(5);
}
w2(4);
break;
case 3:
w2(4); w0(0xc8); cec4; w2(5);
for (k = 0; k < count; k++)
w4(buf[k]);
w2(4);
break;
case 4:
w2(4); w0(0xc8); cec4; w2(5);
for (k = 0; k < count / 2; k++)
w4w(((u16 *)buf)[k]);
w2(4);
break;
case 5:
w2(4); w0(0xc8); cec4; w2(5);
for (k = 0; k < count / 4; k++)
w4l(((u32 *)buf)[k]);
w2(4);
break;
}
}
static void frpw_connect(struct pi_adapter *pi)
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
{
pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(4);
}
static void frpw_disconnect(struct pi_adapter *pi)
{ w2(4); w0(0x20); cec4;
{
w2(4); w0(0x20); cec4;
w0(pi->saved_r0);
w2(pi->saved_r2);
}
/* Stub logic to see if PNP string is available - used to distinguish
between the Xilinx and ASIC implementations of the Freecom adapter.
*/
w2(pi->saved_r2);
}
/*
* Stub logic to see if PNP string is available - used to distinguish
* between the Xilinx and ASIC implementations of the Freecom adapter.
* returns chip_type: 0 = Xilinx, 1 = ASIC
*/
static int frpw_test_pnp(struct pi_adapter *pi)
/* returns chip_type: 0 = Xilinx, 1 = ASIC */
{ int olddelay, a, b;
{
int olddelay, a, b;
#ifdef FRPW_HARD_RESET
w0(0); w2(8); udelay(50); w2(0xc); /* parallel bus reset */
@ -191,7 +200,7 @@ static int frpw_test_pnp(struct pi_adapter *pi)
pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(4); w0(4); w2(6); w2(7);
a = r1() & 0xff; w2(4); b = r1() & 0xff;
w2(0xc); w2(0xe); w2(4);
@ -200,65 +209,70 @@ static int frpw_test_pnp(struct pi_adapter *pi)
w0(pi->saved_r0);
w2(pi->saved_r2);
return ((~a&0x40) && (b&0x40));
}
/* We use the pi->private to remember the result of the PNP test.
To make this work, private = port*2 + chip. Yes, I know it's
a hack :-(
*/
static int frpw_test_proto(struct pi_adapter *pi)
{ int j, k, r;
int e[2] = {0,0};
char scratch[512];
if ((pi->private>>1) != pi->port)
pi->private = frpw_test_pnp(pi) + 2*pi->port;
if (((pi->private%2) == 0) && (pi->mode > 2)) {
dev_dbg(&pi->dev, "frpw: Xilinx does not support mode %d\n", pi->mode);
return 1;
}
if (((pi->private%2) == 1) && (pi->mode == 2)) {
dev_dbg(&pi->dev, "frpw: ASIC does not support mode 2\n");
return 1;
}
frpw_connect(pi);
for (j=0;j<2;j++) {
frpw_write_regr(pi,0,6,0xa0+j*0x10);
for (k=0;k<256;k++) {
frpw_write_regr(pi,0,2,k^0xaa);
frpw_write_regr(pi,0,3,k^0x55);
if (frpw_read_regr(pi,0,2) != (k^0xaa)) e[j]++;
}
}
frpw_disconnect(pi);
frpw_connect(pi);
frpw_read_block_int(pi,scratch,512,0x10);
r = 0;
for (k=0;k<128;k++) if (scratch[k] != k) r++;
frpw_disconnect(pi);
dev_dbg(&pi->dev, "frpw: port 0x%x, chip %ld, mode %d, test=(%d,%d,%d)\n",
pi->port, (pi->private%2), pi->mode, e[0], e[1], r);
return (r || (e[0] && e[1]));
return ((~a & 0x40) && (b & 0x40));
}
/*
* We use the pi->private to remember the result of the PNP test.
* To make this work, private = port*2 + chip. Yes, I know it's a hack :-(
*/
static int frpw_test_proto(struct pi_adapter *pi)
{
int j, k, r;
int e[2] = { 0, 0 };
char scratch[512];
if ((pi->private >> 1) != pi->port)
pi->private = frpw_test_pnp(pi) + 2*pi->port;
if (((pi->private & 0x1) == 0) && (pi->mode > 2)) {
dev_dbg(&pi->dev,
"frpw: Xilinx does not support mode %d\n", pi->mode);
return 1;
}
if (((pi->private & 0x1) == 1) && (pi->mode == 2)) {
dev_dbg(&pi->dev, "frpw: ASIC does not support mode 2\n");
return 1;
}
frpw_connect(pi);
for (j = 0; j < 2; j++) {
frpw_write_regr(pi, 0, 6, 0xa0 + j * 0x10);
for (k = 0; k < 256; k++) {
frpw_write_regr(pi, 0, 2, k ^ 0xaa);
frpw_write_regr(pi, 0, 3, k ^ 0x55);
if (frpw_read_regr(pi, 0, 2) != (k ^ 0xaa))
e[j]++;
}
}
frpw_disconnect(pi);
frpw_connect(pi);
frpw_read_block_int(pi, scratch, 512, 0x10);
r = 0;
for (k = 0; k < 128; k++) {
if (scratch[k] != k)
r++;
}
frpw_disconnect(pi);
dev_dbg(&pi->dev,
"frpw: port 0x%x, chip %ld, mode %d, test=(%d,%d,%d)\n",
pi->port, (pi->private%2), pi->mode, e[0], e[1], r);
return r || (e[0] && e[1]);
}
static void frpw_log_adapter(struct pi_adapter *pi)
{ char *mode_string[6] = {"4-bit","8-bit","EPP",
"EPP-8","EPP-16","EPP-32"};
{
char *mode[6] = { "4-bit", "8-bit", "EPP", "EPP-8", "EPP-16", "EPP-32"};
dev_info(&pi->dev, "Freecom (%s) adapter at 0x%x, mode %d (%s), delay %d\n",
((pi->private % 2) == 0) ? "Xilinx" : "ASIC",
pi->port, pi->mode, mode_string[pi->mode], pi->delay);
dev_info(&pi->dev,
"Freecom (%s) adapter at 0x%x, mode %d (%s), delay %d\n",
((pi->private & 0x1) == 0) ? "Xilinx" : "ASIC",
pi->port, pi->mode, mode[pi->mode], pi->delay);
}
static struct pi_protocol frpw = {

View File

@ -1,16 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
kbic.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU General Public License.
This is a low-level driver for the KBIC-951A and KBIC-971A
parallel to IDE adapter chips from KingByte Information Systems.
The chips are almost identical, however, the wakeup code
required for the 971A interferes with the correct operation of
the 951A, so this driver registers itself twice, once for
each chip.
*/
* (c) 1997-1998 Grant R. Guenther <grant@torque.net>
*
* This is a low-level driver for the KBIC-951A and KBIC-971A
* parallel to IDE adapter chips from KingByte Information Systems.
*
* The chips are almost identical, however, the wakeup code
* required for the 971A interferes with the correct operation of
* the 951A, so this driver registers itself twice, once for
* each chip.
*/
#include <linux/module.h>
#include <linux/init.h>
@ -21,212 +20,223 @@
#include <asm/io.h>
#include "pata_parport.h"
#define r12w() (delay_p,inw(pi->port+1)&0xffff)
#define r12w() (delay_p, inw(pi->port + 1) & 0xffff)
#define j44(a,b) ((((a>>4)&0x0f)|(b&0xf0))^0x88)
#define j53(w) (((w>>3)&0x1f)|((w>>4)&0xe0))
#define j44(a, b) ((((a >> 4) & 0x0f) | (b & 0xf0)) ^ 0x88)
#define j53(w) (((w >> 3) & 0x1f) | ((w >> 4) & 0xe0))
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
*/
static int cont_map[2] = { 0x80, 0x40 };
/*
* cont = 0 - access the IDE register file
* cont = 1 - access the IDE command set
*/
static int cont_map[2] = { 0x80, 0x40 };
static int kbic_read_regr(struct pi_adapter *pi, int cont, int regr)
{
int a, b, s;
{ int a, b, s;
s = cont_map[cont];
s = cont_map[cont];
switch (pi->mode) {
case 0: w0(regr|0x18|s); w2(4); w2(6); w2(4); w2(1); w0(8);
a = r1(); w0(0x28); b = r1(); w2(4);
return j44(a,b);
case 1: w0(regr|0x38|s); w2(4); w2(6); w2(4); w2(5); w0(8);
case 0:
w0(regr | 0x18 | s); w2(4); w2(6); w2(4); w2(1); w0(8);
a = r1(); w0(0x28); b = r1(); w2(4);
return j44(a, b);
case 1:
w0(regr|0x38 | s); w2(4); w2(6); w2(4); w2(5); w0(8);
a = r12w(); w2(4);
return j53(a);
case 2: w0(regr|0x08|s); w2(4); w2(6); w2(4); w2(0xa5); w2(0xa1);
case 2:
w0(regr | 0x08 | s); w2(4); w2(6); w2(4); w2(0xa5); w2(0xa1);
a = r0(); w2(4);
return a;
return a;
case 3:
case 4:
case 5: w0(0x20|s); w2(4); w2(6); w2(4); w3(regr);
case 5:
w0(0x20 | s); w2(4); w2(6); w2(4); w3(regr);
a = r4(); b = r4(); w2(4); w2(0); w2(4);
return a;
}
return -1;
}
}
static void kbic_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{
int s = cont_map[cont];
{ int s;
s = cont_map[cont];
switch (pi->mode) {
case 0:
case 1:
case 2: w0(regr|0x10|s); w2(4); w2(6); w2(4);
switch (pi->mode) {
case 0:
case 1:
case 2:
w0(regr | 0x10 | s); w2(4); w2(6); w2(4);
w0(val); w2(5); w2(4);
break;
case 3:
case 4:
case 5: w0(0x20|s); w2(4); w2(6); w2(4); w3(regr);
case 5:
w0(0x20 | s); w2(4); w2(6); w2(4); w3(regr);
w4(val); w4(val);
w2(4); w2(0); w2(4);
break;
break;
}
}
static void k951_connect(struct pi_adapter *pi)
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(4);
{
pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(4);
}
static void k951_disconnect(struct pi_adapter *pi)
{ w0(pi->saved_r0);
w2(pi->saved_r2);
{
w0(pi->saved_r0);
w2(pi->saved_r2);
}
#define CCP(x) w2(0xc4);w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);\
w0(0x78);w0(x);w2(0xc5);w2(0xc4);w0(0xff);
#define CCP(x) \
do { \
w2(0xc4); w0(0xaa); w0(0x55); \
w0(0); w0(0xff); w0(0x87); \
w0(0x78); w0(x); w2(0xc5); \
w2(0xc4); w0(0xff); \
} while (0)
static void k971_connect(struct pi_adapter *pi)
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
{
pi->saved_r0 = r0();
pi->saved_r2 = r2();
CCP(0x20);
w2(4);
w2(4);
}
static void k971_disconnect(struct pi_adapter *pi)
{ CCP(0x30);
{
CCP(0x30);
w0(pi->saved_r0);
w2(pi->saved_r2);
w2(pi->saved_r2);
}
/* counts must be congruent to 0 MOD 4, but all known applications
have this property.
*/
/*
* count must be congruent to 0 MOD 4, but all known applications
*have this property.
*/
static void kbic_read_block(struct pi_adapter *pi, char *buf, int count)
{
int k, a, b;
{ int k, a, b;
switch (pi->mode) {
case 0: w0(0x98); w2(4); w2(6); w2(4);
for (k=0;k<count/2;k++) {
w2(1); w0(8); a = r1();
w0(0x28); b = r1();
buf[2*k] = j44(a,b);
w2(5); b = r1();
w0(8); a = r1();
buf[2*k+1] = j44(a,b);
switch (pi->mode) {
case 0:
w0(0x98); w2(4); w2(6); w2(4);
for (k = 0; k < count / 2; k++) {
w2(1); w0(8);
a = r1();
w0(0x28);
b = r1();
buf[2 * k] = j44(a, b);
w2(5);
b = r1();
w0(8);
a = r1();
buf[2 * k + 1] = j44(a, b);
w2(4);
}
break;
case 1: w0(0xb8); w2(4); w2(6); w2(4);
for (k=0;k<count/4;k++) {
w0(0xb8);
w2(4); w2(5);
w0(8); buf[4*k] = j53(r12w());
w0(0xb8); buf[4*k+1] = j53(r12w());
}
break;
case 1:
w0(0xb8); w2(4); w2(6); w2(4);
for (k = 0; k < count / 4; k++) {
w0(0xb8);
w2(4); w2(5);
buf[4*k+3] = j53(r12w());
w0(8); buf[4*k+2] = j53(r12w());
}
w2(4);
break;
case 2: w0(0x88); w2(4); w2(6); w2(4);
for (k=0;k<count/2;k++) {
w2(0xa0); w2(0xa1); buf[2*k] = r0();
w2(0xa5); buf[2*k+1] = r0();
}
w2(4);
break;
case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for (k=0;k<count;k++) buf[k] = r4();
w2(4); w2(0); w2(4);
break;
case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
w2(4); w2(0); w2(4);
break;
case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
w2(4); w2(0); w2(4);
break;
}
w0(8);
buf[4 * k] = j53(r12w());
w0(0xb8);
buf[4 * k + 1] = j53(r12w());
w2(4); w2(5);
buf[4 * k + 3] = j53(r12w());
w0(8);
buf[4 * k + 2] = j53(r12w());
}
w2(4);
break;
case 2:
w0(0x88); w2(4); w2(6); w2(4);
for (k = 0; k < count / 2; k++) {
w2(0xa0); w2(0xa1);
buf[2 * k] = r0();
w2(0xa5);
buf[2 * k + 1] = r0();
}
w2(4);
break;
case 3:
w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for (k = 0; k < count; k++)
buf[k] = r4();
w2(4); w2(0); w2(4);
break;
case 4:
w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for (k = 0; k < count / 2; k++)
((u16 *)buf)[k] = r4w();
w2(4); w2(0); w2(4);
break;
case 5:
w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for (k = 0; k < count / 4; k++)
((u32 *)buf)[k] = r4l();
w2(4); w2(0); w2(4);
break;
}
}
static void kbic_write_block(struct pi_adapter *pi, char *buf, int count)
{
int k;
{ int k;
switch (pi->mode) {
case 0:
case 1:
case 2: w0(0x90); w2(4); w2(6); w2(4);
for(k=0;k<count/2;k++) {
w0(buf[2*k+1]); w2(0); w2(4);
w0(buf[2*k]); w2(5); w2(4);
switch (pi->mode) {
case 0:
case 1:
case 2:
w0(0x90); w2(4); w2(6); w2(4);
for (k = 0; k < count / 2; k++) {
w0(buf[2 * k + 1]);
w2(0); w2(4);
w0(buf[2 * k]);
w2(5); w2(4);
}
break;
case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for(k=0;k<count/2;k++) {
w4(buf[2*k+1]);
w4(buf[2*k]);
}
case 3:
w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for (k = 0; k < count / 2; k++) {
w4(buf[2 * k + 1]);
w4(buf[2 * k]);
}
w2(4); w2(0); w2(4);
break;
case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
case 4:
w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for (k = 0; k < count / 2; k++)
w4w(swab16(((u16 *)buf)[k]));
w2(4); w2(0); w2(4);
break;
case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
w2(4); w2(0); w2(4);
break;
case 5:
w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for (k = 0; k < count / 4; k++)
w4l(swab16(((u16 *)buf)[2 * k]) |
swab16(((u16 *)buf)[2 * k + 1]) << 16);
w2(4); w2(0); w2(4);
break;
}
w2(4); w2(0); w2(4);
break;
}
}
static void kbic_log_adapter(struct pi_adapter *pi, char *chip)
{ char *mode_string[6] = {"4-bit","5/3","8-bit",
"EPP-8","EPP_16","EPP-32"};
{
char *mode[6] = { "4-bit", "5/3", "8-bit", "EPP-8", "EPP_16", "EPP-32"};
dev_info(&pi->dev, "KingByte %s at 0x%x, mode %d (%s), delay %d\n",
chip, pi->port, pi->mode, mode_string[pi->mode], pi->delay);
chip, pi->port, pi->mode, mode[pi->mode], pi->delay);
}
static void k951_log_adapter(struct pi_adapter *pi)

View File

@ -1,12 +1,11 @@
/*
ktti.c (c) 1998 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU General Public License.
ktti.c is a low-level protocol driver for the KT Technology
parallel port adapter. This adapter is used in the "PHd"
portable hard-drives. As far as I can tell, this device
supports 4-bit mode _only_.
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 1998 Grant R. Guenther <grant@torque.net>
*
* ktti.c is a low-level protocol driver for the KT Technology
* parallel port adapter. This adapter is used in the "PHd"
* portable hard-drives. As far as I can tell, this device
* supports 4-bit mode _only_.
*/
#include <linux/module.h>
@ -18,80 +17,76 @@
#include <asm/io.h>
#include "pata_parport.h"
#define j44(a,b) (((a>>4)&0x0f)|(b&0xf0))
#define j44(a, b) (((a >> 4) & 0x0f) | (b & 0xf0))
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
*/
static int cont_map[2] = { 0x10, 0x08 };
/*
* cont = 0 - access the IDE register file
* cont = 1 - access the IDE command set
*/
static int cont_map[2] = { 0x10, 0x08 };
static void ktti_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{
int r = regr + cont_map[cont];
{ int r;
r = regr + cont_map[cont];
w0(r); w2(0xb); w2(0xa); w2(3); w2(6);
w0(r); w2(0xb); w2(0xa); w2(3); w2(6);
w0(val); w2(3); w0(0); w2(6); w2(0xb);
}
static int ktti_read_regr(struct pi_adapter *pi, int cont, int regr)
{ int a, b, r;
{
int a, b, r;
r = regr + cont_map[cont];
w0(r); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9);
w0(r); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9);
a = r1(); w2(0xc); b = r1(); w2(9); w2(0xc); w2(9);
return j44(a,b);
return j44(a, b);
}
static void ktti_read_block(struct pi_adapter *pi, char *buf, int count)
{
int k, a, b;
{ int k, a, b;
for (k=0;k<count/2;k++) {
for (k = 0; k < count / 2; k++) {
w0(0x10); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9);
a = r1(); w2(0xc); b = r1(); w2(9);
buf[2*k] = j44(a,b);
buf[2*k] = j44(a, b);
a = r1(); w2(0xc); b = r1(); w2(9);
buf[2*k+1] = j44(a,b);
buf[2*k+1] = j44(a, b);
}
}
static void ktti_write_block(struct pi_adapter *pi, char *buf, int count)
{
int k;
{ int k;
for (k=0;k<count/2;k++) {
for (k = 0; k < count / 2; k++) {
w0(0x10); w2(0xb); w2(0xa); w2(3); w2(6);
w0(buf[2*k]); w2(3);
w0(buf[2*k+1]); w2(6);
w0(buf[2 * k]); w2(3);
w0(buf[2 * k + 1]); w2(6);
w2(0xb);
}
}
static void ktti_connect(struct pi_adapter *pi)
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(0xb); w2(0xa); w0(0); w2(3); w2(6);
{
pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(0xb); w2(0xa); w0(0); w2(3); w2(6);
}
static void ktti_disconnect(struct pi_adapter *pi)
{ w2(0xb); w2(0xa); w0(0xa0); w2(3); w2(4);
{
w2(0xb); w2(0xa); w0(0xa0); w2(3); w2(4);
w0(pi->saved_r0);
w2(pi->saved_r2);
}
w2(pi->saved_r2);
}
static void ktti_log_adapter(struct pi_adapter *pi)
{
dev_info(&pi->dev, "KT adapter at 0x%x, delay %d\n",
pi->port, pi->delay);
pi->port, pi->delay);
}
static struct pi_protocol ktti = {

View File

@ -1,10 +1,10 @@
/*
on20.c (c) 1996-8 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU General Public License.
on20.c is a low-level protocol driver for the
Onspec 90c20 parallel to IDE adapter.
*/
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 1996-1998 Grant R. Guenther <grant@torque.net>
*
* on20.c is a low-level protocol driver for the
* Onspec 90c20 parallel to IDE adapter.
*/
#include <linux/module.h>
#include <linux/init.h>
@ -15,99 +15,114 @@
#include <asm/io.h>
#include "pata_parport.h"
#define op(f) w2(4);w0(f);w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4);
#define vl(v) w2(4);w0(v);w2(5);w2(7);w2(5);w2(4);
#define op(f) \
do { \
w2(4); w0(f); w2(5); w2(0xd); \
w2(5); w2(0xd); w2(5); w2(4); \
} while (0)
#define j44(a,b) (((a>>4)&0x0f)|(b&0xf0))
#define vl(v) \
do { \
w2(4); w0(v); w2(5); \
w2(7); w2(5); w2(4); \
} while (0)
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
*/
#define j44(a, b) (((a >> 4) & 0x0f) | (b & 0xf0))
/*
* cont = 0 - access the IDE register file
* cont = 1 - access the IDE command set
*/
static int on20_read_regr(struct pi_adapter *pi, int cont, int regr)
{
int h, l, r;
{ int h,l, r ;
r = (regr << 2) + 1 + cont;
r = (regr<<2) + 1 + cont;
op(1); vl(r); op(0);
switch (pi->mode) {
case 0: w2(4); w2(6); l = r1();
w2(4); w2(6); h = r1();
w2(4); w2(6); w2(4); w2(6); w2(4);
return j44(l,h);
case 1: w2(4); w2(0x26); r = r0();
w2(4); w2(0x26); w2(4);
return r;
op(1); vl(r); op(0);
switch (pi->mode) {
case 0:
w2(4); w2(6); l = r1();
w2(4); w2(6); h = r1();
w2(4); w2(6); w2(4); w2(6); w2(4);
return j44(l, h);
case 1:
w2(4); w2(0x26); r = r0();
w2(4); w2(0x26); w2(4);
return r;
}
return -1;
}
}
static void on20_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{
int r = (regr << 2) + 1 + cont;
{ int r;
r = (regr<<2) + 1 + cont;
op(1); vl(r);
op(0); vl(val);
op(1); vl(r);
op(0); vl(val);
op(0); vl(val);
}
static void on20_connect(struct pi_adapter *pi)
{
pi->saved_r0 = r0();
pi->saved_r2 = r2();
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
w2(4);w0(0);w2(0xc);w2(4);w2(6);w2(4);w2(6);w2(4);
if (pi->mode) { op(2); vl(8); op(2); vl(9); }
else { op(2); vl(0); op(2); vl(8); }
w2(4); w0(0); w2(0xc); w2(4); w2(6); w2(4); w2(6); w2(4);
if (pi->mode) {
op(2); vl(8); op(2); vl(9);
} else {
op(2); vl(0); op(2); vl(8);
}
}
static void on20_disconnect(struct pi_adapter *pi)
{ w2(4);w0(7);w2(4);w2(0xc);w2(4);
w0(pi->saved_r0);
w2(pi->saved_r2);
}
{
w2(4); w0(7); w2(4); w2(0xc); w2(4);
w0(pi->saved_r0);
w2(pi->saved_r2);
}
static void on20_read_block(struct pi_adapter *pi, char *buf, int count)
{ int k, l, h;
{
int k, l, h;
op(1); vl(1); op(0);
for (k=0;k<count;k++)
if (pi->mode) {
w2(4); w2(0x26); buf[k] = r0();
} else {
w2(6); l = r1(); w2(4);
w2(6); h = r1(); w2(4);
buf[k] = j44(l,h);
}
for (k = 0; k < count; k++) {
if (pi->mode) {
w2(4); w2(0x26); buf[k] = r0();
} else {
w2(6); l = r1(); w2(4);
w2(6); h = r1(); w2(4);
buf[k] = j44(l, h);
}
}
w2(4);
}
static void on20_write_block(struct pi_adapter *pi, char *buf, int count)
{ int k;
{
int k;
op(1); vl(1); op(0);
for (k=0;k<count;k++) { w2(5); w0(buf[k]); w2(7); }
for (k = 0; k < count; k++) {
w2(5); w0(buf[k]); w2(7);
}
w2(4);
}
static void on20_log_adapter(struct pi_adapter *pi)
{
char *mode_string[2] = { "4-bit", "8-bit" };
{ char *mode_string[2] = {"4-bit","8-bit"};
dev_info(&pi->dev, "OnSpec 90c20 at 0x%x, mode %d (%s), delay %d\n",
pi->port, pi->mode, mode_string[pi->mode], pi->delay);
dev_info(&pi->dev,
"OnSpec 90c20 at 0x%x, mode %d (%s), delay %d\n",
pi->port, pi->mode, mode_string[pi->mode], pi->delay);
}
static struct pi_protocol on20 = {

View File

@ -1,11 +1,10 @@
/*
on26.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU General Public License.
on26.c is a low-level protocol driver for the
OnSpec 90c26 parallel to IDE adapter chip.
*/
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* (c) 1997-1998 Grant R. Guenther <grant@torque.net>
*
* on26.c is a low-level protocol driver for the
* OnSpec 90c26 parallel to IDE adapter chip.
*/
#include <linux/module.h>
#include <linux/init.h>
@ -16,260 +15,281 @@
#include <asm/io.h>
#include "pata_parport.h"
/* mode codes: 0 nybble reads, 8-bit writes
1 8-bit reads and writes
2 8-bit EPP mode
3 EPP-16
4 EPP-32
*/
/*
* mode codes: 0 nybble reads, 8-bit writes
* 1 8-bit reads and writes
* 2 8-bit EPP mode
* 3 EPP-16
* 4 EPP-32
*/
#define j44(a,b) (((a>>4)&0x0f)|(b&0xf0))
#define j44(a, b) (((a >> 4) & 0x0f) | (b & 0xf0))
#define P1 w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4);
#define P2 w2(5);w2(7);w2(5);w2(4);
#define P1 \
do { \
w2(5); w2(0xd); w2(5); w2(0xd); w2(5); w2(4); \
} while (0)
/* cont = 0 - access the IDE register file
cont = 1 - access the IDE command set
*/
#define P2 \
do { \
w2(5); w2(7); w2(5); w2(4); \
} while (0)
/*
* cont = 0 - access the IDE register file
* cont = 1 - access the IDE command set
*/
static int on26_read_regr(struct pi_adapter *pi, int cont, int regr)
{
int a, b, r;
{ int a, b, r;
r = (regr << 2) + 1 + cont;
r = (regr<<2) + 1 + cont;
switch (pi->mode) {
case 0: w0(1); P1; w0(r); P2; w0(0); P1;
switch (pi->mode) {
case 0:
w0(1); P1; w0(r); P2; w0(0); P1;
w2(6); a = r1(); w2(4);
w2(6); b = r1(); w2(4);
w2(6); w2(4); w2(6); w2(4);
return j44(a,b);
case 1: w0(1); P1; w0(r); P2; w0(0); P1;
return j44(a, b);
case 1:
w0(1); P1; w0(r); P2; w0(0); P1;
w2(0x26); a = r0(); w2(4); w2(0x26); w2(4);
return a;
return a;
case 2:
case 3:
case 4: w3(1); w3(1); w2(5); w4(r); w2(4);
case 4:
w3(1); w3(1); w2(5); w4(r); w2(4);
w3(0); w3(0); w2(0x24); a = r4(); w2(4);
w2(0x24); (void)r4(); w2(4);
return a;
return a;
}
}
return -1;
}
static void on26_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{ int r;
r = (regr<<2) + 1 + cont;
switch (pi->mode) {
case 0:
case 1: w0(1); P1; w0(r); P2; w0(0); P1;
w0(val); P2; w0(val); P2;
break;
case 2:
case 3:
case 4: w3(1); w3(1); w2(5); w4(r); w2(4);
w3(0); w3(0);
w2(5); w4(val); w2(4);
w2(5); w4(val); w2(4);
break;
}
return -1;
}
#define CCP(x) w0(0xfe);w0(0xaa);w0(0x55);w0(0);w0(0xff);\
w0(0x87);w0(0x78);w0(x);w2(4);w2(5);w2(4);w0(0xff);
static void on26_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{
int r = (regr << 2) + 1 + cont;
switch (pi->mode) {
case 0:
case 1:
w0(1); P1; w0(r); P2; w0(0); P1;
w0(val); P2; w0(val); P2;
break;
case 2:
case 3:
case 4:
w3(1); w3(1); w2(5); w4(r); w2(4);
w3(0); w3(0);
w2(5); w4(val); w2(4);
w2(5); w4(val); w2(4);
break;
}
}
#define CCP(x) \
do { \
w0(0xfe); w0(0xaa); w0(0x55); w0(0); \
w0(0xff); w0(0x87); w0(0x78); w0(x); \
w2(4); w2(5); w2(4); w0(0xff); \
} while (0)
static void on26_connect(struct pi_adapter *pi)
{ int x;
{
int x;
pi->saved_r0 = r0();
pi->saved_r2 = r2();
pi->saved_r2 = r2();
CCP(0x20);
x = 8; if (pi->mode) x = 9;
CCP(0x20);
if (pi->mode)
x = 9;
else
x = 8;
w0(2); P1; w0(8); P2;
w0(2); P1; w0(x); P2;
}
static void on26_disconnect(struct pi_adapter *pi)
{ if (pi->mode >= 2) { w3(4); w3(4); w3(4); w3(4); }
else { w0(4); P1; w0(4); P1; }
{
if (pi->mode >= 2) {
w3(4); w3(4); w3(4); w3(4);
} else {
w0(4); P1; w0(4); P1;
}
CCP(0x30);
w0(pi->saved_r0);
w2(pi->saved_r2);
}
w0(pi->saved_r0);
w2(pi->saved_r2);
}
#define RESET_WAIT 200
static int on26_test_port(struct pi_adapter *pi) /* hard reset */
/* hard reset */
static int on26_test_port(struct pi_adapter *pi)
{
int i, m, d, x = 0, y = 0;
{ int i, m, d, x=0, y=0;
pi->saved_r0 = r0();
pi->saved_r2 = r2();
pi->saved_r0 = r0();
pi->saved_r2 = r2();
d = pi->delay;
m = pi->mode;
pi->delay = 5;
pi->mode = 0;
d = pi->delay;
m = pi->mode;
pi->delay = 5;
pi->mode = 0;
w2(0xc);
w2(0xc);
CCP(0x30); CCP(0);
CCP(0x30); CCP(0);
w0(0xfe); w0(0xaa); w0(0x55); w0(0); w0(0xff);
i = ((r1() & 0xf0) << 4); w0(0x87);
i |= (r1() & 0xf0); w0(0x78);
w0(0x20); w2(4); w2(5);
i |= ((r1() & 0xf0) >> 4);
w2(4); w0(0xff);
w0(0xfe);w0(0xaa);w0(0x55);w0(0);w0(0xff);
i = ((r1() & 0xf0) << 4); w0(0x87);
i |= (r1() & 0xf0); w0(0x78);
w0(0x20);w2(4);w2(5);
i |= ((r1() & 0xf0) >> 4);
w2(4);w0(0xff);
if (i == 0xb5f) {
w0(2); P1; w0(0); P2;
w0(3); P1; w0(0); P2;
w0(2); P1; w0(8); P2; udelay(100);
w0(2); P1; w0(0xa); P2; udelay(100);
w0(2); P1; w0(8); P2; udelay(1000);
if (i == 0xb5f) {
on26_write_regr(pi, 0, 6, 0xa0);
w0(2); P1; w0(0); P2;
w0(3); P1; w0(0); P2;
w0(2); P1; w0(8); P2; udelay(100);
w0(2); P1; w0(0xa); P2; udelay(100);
w0(2); P1; w0(8); P2; udelay(1000);
on26_write_regr(pi,0,6,0xa0);
for (i = 0; i < RESET_WAIT; i++) {
on26_write_regr(pi, 0, 6, 0xa0);
x = on26_read_regr(pi, 0, 7);
on26_write_regr(pi, 0, 6, 0xb0);
y = on26_read_regr(pi, 0, 7);
if (!((x & 0x80) || (y & 0x80)))
break;
mdelay(100);
}
for (i=0;i<RESET_WAIT;i++) {
on26_write_regr(pi,0,6,0xa0);
x = on26_read_regr(pi,0,7);
on26_write_regr(pi,0,6,0xb0);
y = on26_read_regr(pi,0,7);
if (!((x&0x80)||(y&0x80))) break;
mdelay(100);
}
if (i == RESET_WAIT)
dev_err(&pi->dev,
"on26: Device reset failed (%x,%x)\n", x, y);
if (i == RESET_WAIT)
dev_err(&pi->dev, "on26: Device reset failed (%x,%x)\n", x, y);
w0(4); P1; w0(4); P1;
}
w0(4); P1; w0(4); P1;
}
CCP(0x30);
CCP(0x30);
pi->delay = d;
pi->mode = m;
w0(pi->saved_r0);
w2(pi->saved_r2);
pi->delay = d;
pi->mode = m;
w0(pi->saved_r0);
w2(pi->saved_r2);
return 5;
return 5;
}
static void on26_read_block(struct pi_adapter *pi, char *buf, int count)
{
int k, a, b;
{ int k, a, b;
switch (pi->mode) {
case 0: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x18); P2; w0(0); P1;
switch (pi->mode) {
case 0:
w0(1); P1; w0(1); P2; w0(2); P1; w0(0x18); P2; w0(0); P1;
udelay(10);
for (k=0;k<count;k++) {
w2(6); a = r1();
w2(4); b = r1();
buf[k] = j44(a,b);
}
w0(2); P1; w0(8); P2;
break;
case 1: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x19); P2; w0(0); P1;
for (k = 0; k < count; k++) {
w2(6); a = r1();
w2(4); b = r1();
buf[k] = j44(a, b);
}
w0(2); P1; w0(8); P2;
break;
case 1:
w0(1); P1; w0(1); P2; w0(2); P1; w0(0x19); P2; w0(0); P1;
udelay(10);
for (k=0;k<count/2;k++) {
w2(0x26); buf[2*k] = r0();
w2(0x24); buf[2*k+1] = r0();
}
w0(2); P1; w0(9); P2;
break;
case 2: w3(1); w3(1); w2(5); w4(1); w2(4);
for (k = 0; k < count / 2; k++) {
w2(0x26); buf[2 * k] = r0();
w2(0x24); buf[2 * k + 1] = r0();
}
w0(2); P1; w0(9); P2;
break;
case 2:
w3(1); w3(1); w2(5); w4(1); w2(4);
w3(0); w3(0); w2(0x24);
udelay(10);
for (k=0;k<count;k++) buf[k] = r4();
w2(4);
break;
case 3: w3(1); w3(1); w2(5); w4(1); w2(4);
w3(0); w3(0); w2(0x24);
udelay(10);
for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
w2(4);
break;
case 4: w3(1); w3(1); w2(5); w4(1); w2(4);
w3(0); w3(0); w2(0x24);
udelay(10);
for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
w2(4);
break;
}
for (k = 0; k < count; k++)
buf[k] = r4();
w2(4);
break;
case 3:
w3(1); w3(1); w2(5); w4(1); w2(4);
w3(0); w3(0); w2(0x24);
udelay(10);
for (k = 0; k < count / 2; k++)
((u16 *)buf)[k] = r4w();
w2(4);
break;
case 4:
w3(1); w3(1); w2(5); w4(1); w2(4);
w3(0); w3(0); w2(0x24);
udelay(10);
for (k = 0; k < count / 4; k++)
((u32 *)buf)[k] = r4l();
w2(4);
break;
}
}
static void on26_write_block(struct pi_adapter *pi, char *buf, int count)
{
int k;
{ int k;
switch (pi->mode) {
case 0:
case 1: w0(1); P1; w0(1); P2;
w0(2); P1; w0(0x18+pi->mode); P2; w0(0); P1;
switch (pi->mode) {
case 0:
case 1:
w0(1); P1; w0(1); P2;
w0(2); P1; w0(0x18 + pi->mode); P2; w0(0); P1;
udelay(10);
for (k=0;k<count/2;k++) {
w2(5); w0(buf[2*k]);
w2(7); w0(buf[2*k+1]);
}
w2(5); w2(4);
w0(2); P1; w0(8+pi->mode); P2;
break;
case 2: w3(1); w3(1); w2(5); w4(1); w2(4);
for (k = 0; k < count / 2; k++) {
w2(5); w0(buf[2 * k]);
w2(7); w0(buf[2 * k + 1]);
}
w2(5); w2(4);
w0(2); P1; w0(8 + pi->mode); P2;
break;
case 2:
w3(1); w3(1); w2(5); w4(1); w2(4);
w3(0); w3(0); w2(0xc5);
udelay(10);
for (k=0;k<count;k++) w4(buf[k]);
for (k = 0; k < count; k++)
w4(buf[k]);
w2(0xc4);
break;
case 3: w3(1); w3(1); w2(5); w4(1); w2(4);
w3(0); w3(0); w2(0xc5);
udelay(10);
for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
w2(0xc4);
break;
case 4: w3(1); w3(1); w2(5); w4(1); w2(4);
w3(0); w3(0); w2(0xc5);
udelay(10);
for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
w2(0xc4);
break;
}
break;
case 3:
w3(1); w3(1); w2(5); w4(1); w2(4);
w3(0); w3(0); w2(0xc5);
udelay(10);
for (k = 0; k < count / 2; k++)
w4w(((u16 *)buf)[k]);
w2(0xc4);
break;
case 4:
w3(1); w3(1); w2(5); w4(1); w2(4);
w3(0); w3(0); w2(0xc5);
udelay(10);
for (k = 0; k < count / 4; k++)
w4l(((u32 *)buf)[k]);
w2(0xc4);
break;
}
}
static void on26_log_adapter(struct pi_adapter *pi)
{
char *mode_string[5] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" };
{ char *mode_string[5] = {"4-bit","8-bit","EPP-8",
"EPP-16","EPP-32"};
dev_info(&pi->dev, "OnSpec 90c26 at 0x%x, mode %d (%s), delay %d\n",
pi->port, pi->mode, mode_string[pi->mode], pi->delay);
dev_info(&pi->dev,
"OnSpec 90c26 at 0x%x, mode %d (%s), delay %d\n",
pi->port, pi->mode, mode_string[pi->mode], pi->delay);
}
static struct pi_protocol on26 = {

View File

@ -223,7 +223,7 @@ static int pata_platform_probe(struct platform_device *pdev)
static struct platform_driver pata_platform_driver = {
.probe = pata_platform_probe,
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
.driver = {
.name = DRV_NAME,
},

View File

@ -614,7 +614,7 @@ static SIMPLE_DEV_PM_OPS(ahci_highbank_pm_ops,
ahci_highbank_suspend, ahci_highbank_resume);
static struct platform_driver ahci_highbank_driver = {
.remove = ata_platform_remove_one,
.remove_new = ata_platform_remove_one,
.driver = {
.name = "highbank-ahci",
.of_match_table = ahci_of_match,

View File

@ -32,6 +32,7 @@
#include <scsi/scsi.h>
#include <linux/libata.h>
#include <linux/of.h>
#include <linux/of_address.h>
#define DRV_NAME "sata_svw"
#define DRV_VERSION "2.3"
@ -319,10 +320,11 @@ static int k2_sata_show_info(struct seq_file *m, struct Scsi_Host *shost)
/* Match it to a port node */
index = (ap == ap->host->ports[0]) ? 0 : 1;
for (np = np->child; np != NULL; np = np->sibling) {
const u32 *reg = of_get_property(np, "reg", NULL);
if (!reg)
u64 reg;
if (of_property_read_reg(np, 0, &reg, NULL))
continue;
if (index == *reg) {
if (index == reg) {
seq_printf(m, "devspec: %pOF\n", np);
break;
}

View File

@ -872,8 +872,7 @@ int sas_change_queue_depth(struct scsi_device *sdev, int depth)
struct domain_device *dev = sdev_to_domain_dev(sdev);
if (dev_is_sata(dev))
return ata_change_queue_depth(dev->sata_dev.ap,
sas_to_ata_dev(dev), sdev, depth);
return ata_change_queue_depth(dev->sata_dev.ap, sdev, depth);
if (!sdev->tagged_supported)
depth = 1;

View File

@ -1144,8 +1144,8 @@ extern int ata_scsi_slave_config(struct scsi_device *sdev);
extern void ata_scsi_slave_destroy(struct scsi_device *sdev);
extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
int queue_depth);
extern int ata_change_queue_depth(struct ata_port *ap, struct ata_device *dev,
struct scsi_device *sdev, int queue_depth);
extern int ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev,
int queue_depth);
extern struct ata_device *ata_dev_pair(struct ata_device *adev);
extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev);
extern void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap);
@ -1276,7 +1276,7 @@ extern int ata_pci_device_resume(struct pci_dev *pdev);
struct platform_device;
extern int ata_platform_remove_one(struct platform_device *pdev);
extern void ata_platform_remove_one(struct platform_device *pdev);
/*
* ACPI - drivers/ata/libata-acpi.c