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

View File

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

View File

@ -31,8 +31,14 @@ properties:
- const: pipe - const: pipe
resets: resets:
minItems: 1
maxItems: 2
reset-names:
minItems: 1
items: items:
- description: exclusive PHY reset line - const: phy
- const: apb
rockchip,enable-ssc: rockchip,enable-ssc:
type: boolean type: boolean
@ -78,6 +84,32 @@ required:
- rockchip,pipe-phy-grf - rockchip,pipe-phy-grf
- "#phy-cells" - "#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 additionalProperties: false
examples: examples:

View File

@ -544,7 +544,7 @@ out_reset:
return ret; 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 ata_host *host = dev_get_drvdata(&pdev->dev);
struct ahci_host_priv *hpriv = host->private_data; 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); 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) 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 = { static struct platform_driver brcm_ahci_driver = {
.probe = brcm_ahci_probe, .probe = brcm_ahci_probe,
.remove = brcm_ahci_remove, .remove_new = brcm_ahci_remove,
.shutdown = brcm_ahci_shutdown, .shutdown = brcm_ahci_shutdown,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,

View File

@ -369,7 +369,7 @@ MODULE_DEVICE_TABLE(of, ceva_ahci_of_match);
static struct platform_driver ceva_ahci_driver = { static struct platform_driver ceva_ahci_driver = {
.probe = ceva_ahci_probe, .probe = ceva_ahci_probe,
.remove = ata_platform_remove_one, .remove_new = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = ceva_ahci_of_match, .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 = { static struct platform_driver ahci_da850_driver = {
.probe = ahci_da850_probe, .probe = ahci_da850_probe,
.remove = ata_platform_remove_one, .remove_new = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = ahci_da850_of_match, .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 = { static struct platform_driver ahci_dm816_driver = {
.probe = ahci_dm816_probe, .probe = ahci_dm816_probe,
.remove = ata_platform_remove_one, .remove_new = ata_platform_remove_one,
.driver = { .driver = {
.name = AHCI_DM816_DRV_NAME, .name = AHCI_DM816_DRV_NAME,
.of_match_table = ahci_dm816_of_match, .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 = { static struct platform_driver ahci_dwc_driver = {
.probe = ahci_dwc_probe, .probe = ahci_dwc_probe,
.remove = ata_platform_remove_one, .remove_new = ata_platform_remove_one,
.shutdown = ahci_platform_shutdown, .shutdown = ahci_platform_shutdown,
.driver = { .driver = {
.name = DRV_NAME, .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 = { static struct platform_driver imx_ahci_driver = {
.probe = imx_ahci_probe, .probe = imx_ahci_probe,
.remove = ata_platform_remove_one, .remove_new = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = imx_ahci_of_match, .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 = { static struct platform_driver mtk_ahci_driver = {
.probe = mtk_ahci_probe, .probe = mtk_ahci_probe,
.remove = ata_platform_remove_one, .remove_new = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = ahci_of_match, .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 = { static struct platform_driver ahci_mvebu_driver = {
.probe = ahci_mvebu_probe, .probe = ahci_mvebu_probe,
.remove = ata_platform_remove_one, .remove_new = ata_platform_remove_one,
.suspend = ahci_mvebu_suspend, .suspend = ahci_mvebu_suspend,
.resume = ahci_mvebu_resume, .resume = ahci_mvebu_resume,
.driver = { .driver = {

View File

@ -16,7 +16,6 @@
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <asm/octeon/octeon.h> #include <asm/octeon/octeon.h>
#include <asm/bitfield.h>
#define CVMX_SATA_UCTL_SHIM_CFG 0xE8 #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 = { static struct platform_driver ahci_driver = {
.probe = ahci_probe, .probe = ahci_probe,
.remove = ata_platform_remove_one, .remove_new = ata_platform_remove_one,
.shutdown = ahci_platform_shutdown, .shutdown = ahci_platform_shutdown,
.driver = { .driver = {
.name = DRV_NAME, .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 = { static struct platform_driver ahci_qoriq_driver = {
.probe = ahci_qoriq_probe, .probe = ahci_qoriq_probe,
.remove = ata_platform_remove_one, .remove_new = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = ahci_qoriq_of_match, .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 = { static struct platform_driver ahci_seattle_driver = {
.probe = ahci_seattle_probe, .probe = ahci_seattle_probe,
.remove = ata_platform_remove_one, .remove_new = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.acpi_match_table = ahci_acpi_match, .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, .of_match_table = st_ahci_match,
}, },
.probe = st_ahci_probe, .probe = st_ahci_probe,
.remove = ata_platform_remove_one, .remove_new = ata_platform_remove_one,
}; };
module_platform_driver(st_ahci_driver); 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 = { static struct platform_driver ahci_sunxi_driver = {
.probe = ahci_sunxi_probe, .probe = ahci_sunxi_probe,
.remove = ata_platform_remove_one, .remove_new = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = ahci_sunxi_of_match, .of_match_table = ahci_sunxi_of_match,

View File

@ -609,7 +609,7 @@ deinit_controller:
static struct platform_driver tegra_ahci_driver = { static struct platform_driver tegra_ahci_driver = {
.probe = tegra_ahci_probe, .probe = tegra_ahci_probe,
.remove = ata_platform_remove_one, .remove_new = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = tegra_ahci_of_match, .of_match_table = tegra_ahci_of_match,

View File

@ -868,7 +868,7 @@ disable_resources:
static struct platform_driver xgene_ahci_driver = { static struct platform_driver xgene_ahci_driver = {
.probe = xgene_ahci_probe, .probe = xgene_ahci_probe,
.remove = ata_platform_remove_one, .remove_new = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = xgene_ahci_of_match, .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; void __iomem *mmio = hpriv->mmio;
u32 tmp; 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); ahci_enable_ahci(mmio);
/* global controller reset */ /* Global controller reset */
if (!ahci_skip_host_reset) { if (ahci_skip_host_reset) {
tmp = readl(mmio + HOST_CTL); dev_info(host->dev, "Skipping global host reset\n");
if ((tmp & HOST_RESET) == 0) { return 0;
writel(tmp | HOST_RESET, mmio + HOST_CTL); }
readl(mmio + HOST_CTL); /* flush */
}
/* tmp = readl(mmio + HOST_CTL);
* to perform host reset, OS should set HOST_RESET if (!(tmp & HOST_RESET)) {
* and poll until this bit is read to be "0". writel(tmp | HOST_RESET, mmio + HOST_CTL);
* reset must complete within 1 second, or readl(mmio + HOST_CTL); /* flush */
* 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", * To perform host reset, OS should set HOST_RESET and poll until this
tmp); * bit is read to be "0". Reset must complete within 1 second, or the
return -EIO; * 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 */ /* Turn on AHCI mode */
ahci_enable_ahci(mmio); ahci_enable_ahci(mmio);
/* Some registers might be cleared on reset. Restore /* Some registers might be cleared on reset. Restore initial values. */
* initial values. if (!(hpriv->flags & AHCI_HFLAG_NO_WRITE_TO_RO))
*/ ahci_restore_initial_config(host);
if (!(hpriv->flags & AHCI_HFLAG_NO_WRITE_TO_RO))
ahci_restore_initial_config(host);
} else
dev_info(host->dev, "skipping global host reset\n");
return 0; return 0;
} }

View File

@ -3802,11 +3802,7 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
return -ENODEV; return -ENODEV;
/* fail early if !ATA && !ATAPI to avoid issuing [P]IDENTIFY to PMP */ /* fail early if !ATA && !ATAPI to avoid issuing [P]IDENTIFY to PMP */
if (ata_class_enabled(new_class) && if (ata_class_enabled(new_class) && new_class == ATA_DEV_PMP) {
new_class != ATA_DEV_ATA &&
new_class != ATA_DEV_ATAPI &&
new_class != ATA_DEV_ZAC &&
new_class != ATA_DEV_SEMB) {
ata_dev_info(dev, "class mismatch %u != %u\n", ata_dev_info(dev, "class mismatch %u != %u\n",
dev->class, new_class); dev->class, new_class);
rc = -ENODEV; rc = -ENODEV;
@ -6142,13 +6138,11 @@ EXPORT_SYMBOL_GPL(ata_pci_device_resume);
* LOCKING: * LOCKING:
* Inherited from platform layer (may sleep). * 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); struct ata_host *host = platform_get_drvdata(pdev);
ata_host_detach(host); ata_host_detach(host);
return 0;
} }
EXPORT_SYMBOL_GPL(ata_platform_remove_one); 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); verdict = ata_eh_speed_down_verdict(dev);
/* turn off NCQ? */ /* turn off NCQ? */
if ((verdict & ATA_EH_SPDN_NCQ_OFF) && if ((verdict & ATA_EH_SPDN_NCQ_OFF) && ata_ncq_enabled(dev)) {
(dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ |
ATA_DFLAG_NCQ_OFF)) == ATA_DFLAG_NCQ) {
dev->flags |= ATA_DFLAG_NCQ_OFF; dev->flags |= ATA_DFLAG_NCQ_OFF;
ata_dev_warn(dev, "NCQ disabled due to excessive errors\n"); ata_dev_warn(dev, "NCQ disabled due to excessive errors\n");
goto done; goto done;
@ -3813,16 +3811,29 @@ void ata_eh_finish(struct ata_port *ap)
* generate sense data in this function, * generate sense data in this function,
* considering both err_mask and tf. * 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); ata_eh_qc_retry(qc);
else } else {
ata_eh_qc_complete(qc); ata_eh_qc_complete(qc);
}
} else { } else {
if (qc->flags & ATA_QCFLAG_SENSE_VALID) { if (qc->flags & ATA_QCFLAG_SENSE_VALID) {
ata_eh_qc_complete(qc); ata_eh_qc_complete(qc);
} else { } else {
/* feed zero TF to sense generation */ /* feed zero TF to sense generation */
memset(&qc->result_tf, 0, sizeof(qc->result_tf)); 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); 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 * ata_change_queue_depth - Set a device maximum queue depth
* @ap: ATA port of the target device * @ap: ATA port of the target device
* @dev: target ATA device
* @sdev: SCSI device to configure queue depth for * @sdev: SCSI device to configure queue depth for
* @queue_depth: new queue depth * @queue_depth: new queue depth
* *
@ -1031,33 +1030,47 @@ EXPORT_SYMBOL_GPL(dev_attr_sw_activity);
* and libata. * and libata.
* *
*/ */
int ata_change_queue_depth(struct ata_port *ap, struct ata_device *dev, int ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev,
struct scsi_device *sdev, int queue_depth) int queue_depth)
{ {
struct ata_device *dev;
unsigned long flags; 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); 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; dev->flags |= ATA_DFLAG_NCQ_OFF;
queue_depth = 1; queue_depth = 1;
} else {
dev->flags &= ~ATA_DFLAG_NCQ_OFF;
} }
spin_unlock_irqrestore(ap->lock, flags); spin_unlock_irqrestore(ap->lock, flags);
/* limit and apply queue depth */ if (queue_depth == sdev->queue_depth)
queue_depth = min(queue_depth, sdev->host->can_queue); return sdev->queue_depth;
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;
return scsi_change_queue_depth(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); struct ata_port *ap = ata_shost_to_port(sdev->host);
return ata_change_queue_depth(ap, ata_scsi_find_dev(ap, sdev), return ata_change_queue_depth(ap, sdev, queue_depth);
sdev, queue_depth);
} }
EXPORT_SYMBOL_GPL(ata_scsi_change_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) if (dev->flags & ATA_DFLAG_AN)
set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events); 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(sdev->host->can_queue, ata_id_queue_depth(dev->id));
depth = min(ATA_MAX_QUEUE, depth); depth = min(ATA_MAX_QUEUE, depth);
scsi_change_queue_depth(sdev, 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, .of_match_table = ixp4xx_pata_of_match,
}, },
.probe = ixp4xx_pata_probe, .probe = ixp4xx_pata_probe,
.remove = ata_platform_remove_one, .remove_new = ata_platform_remove_one,
}; };
module_platform_driver(ixp4xx_pata_platform_driver); module_platform_driver(ixp4xx_pata_platform_driver);

View File

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

View File

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

View File

@ -1,11 +1,10 @@
/* // SPDX-License-Identifier: GPL-2.0-or-later
bpck.c (c) 1996-8 Grant R. Guenther <grant@torque.net> /*
Under the terms of the GNU General Public License. * (c) 1996-1998 Grant R. Guenther <grant@torque.net>
*
bpck.c is a low-level protocol driver for the MicroSolutions * bpck.c is a low-level protocol driver for the MicroSolutions
"backpack" parallel port IDE adapter. * "backpack" parallel port IDE adapter.
*/
*/
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
@ -29,59 +28,57 @@
#define j44(l,h) (((l>>3)&0x7)|((l>>4)&0x8)|((h<<1)&0x70)|(h&0x80)) #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 = 0 - access the IDE register file
cont = 2 - use internal bpck register addressing * cont = 1 - access the IDE command set
*/ * cont = 2 - use internal bpck register addressing
*/
static int cont_map[3] = { 0x40, 0x48, 0 }; static int cont_map[3] = { 0x40, 0x48, 0 };
static int bpck_read_regr(struct pi_adapter *pi, int cont, int regr) 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]; r = regr + cont_map[cont];
switch (pi->mode) { switch (pi->mode) {
case 0:
case 0: w0(r & 0xf); w0(r); t2(2); t2(4); w0(r & 0xf); w0(r); t2(2); t2(4);
l = r1(); l = r1();
t2(4); t2(4);
h = r1(); h = r1();
return j44(l,h); return j44(l, h);
case 1:
case 1: w0(r & 0xf); w0(r); t2(2); w0(r & 0xf); w0(r); t2(2);
e2(); t2(0x20); e2(); t2(0x20);
t2(4); h = r0(); t2(4); h = r0();
t2(1); t2(0x20); t2(1); t2(0x20);
return h; return h;
case 2: case 2:
case 3: case 3:
case 4: w0(r); w2(9); w2(0); w2(0x20); case 4:
w0(r); w2(9); w2(0); w2(0x20);
h = r4(); h = r4();
w2(0); w2(0);
return h; return h;
} }
return -1; return -1;
} }
static void bpck_write_regr(struct pi_adapter *pi, int cont, int regr, int val) static void bpck_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{
{ int r; int r;
r = regr + cont_map[cont]; r = regr + cont_map[cont];
switch (pi->mode) { switch (pi->mode) {
case 0: case 0:
case 1: w0(r); case 1: w0(r);
t2(2); t2(2);
w0(val); w0(val);
o2(); t2(4); t2(1); o2(); t2(4); t2(1);
break; break;
case 2: case 2:
case 3: case 3:
case 4: w0(r); w2(9); w2(0); 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)) #define RR(r) (bpck_read_regr(pi,2,r))
static void bpck_write_block(struct pi_adapter *pi, char *buf, int count) static void bpck_write_block(struct pi_adapter *pi, char *buf, int count)
{
{ int i; int i;
switch (pi->mode) { switch (pi->mode) {
case 0: WR(4,0x40); case 0:
WR(4, 0x40);
w0(0x40); t2(2); t2(1); w0(0x40); t2(2); t2(1);
for (i=0;i<count;i++) { w0(buf[i]); t2(4); } for (i = 0; i < count; i++) {
WR(4,0); w0(buf[i]);
t2(4);
}
WR(4, 0);
break; break;
case 1: WR(4,0x50); case 1:
w0(0x40); t2(2); t2(1); WR(4, 0x50);
for (i=0;i<count;i++) { w0(buf[i]); t2(4); } w0(0x40); t2(2); t2(1);
WR(4,0x10); for (i = 0; i < count; i++) {
w0(buf[i]);
t2(4);
}
WR(4, 0x10);
break; break;
case 2: WR(4,0x48); case 2:
WR(4, 0x48);
w0(0x40); w2(9); w2(0); w2(1); 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); w2(0);
WR(4,8); WR(4, 8);
break; break;
case 3: WR(4,0x48); case 3:
w0(0x40); w2(9); w2(0); w2(1); WR(4, 0x48);
for (i=0;i<count/2;i++) w4w(((u16 *)buf)[i]); w0(0x40); w2(9); w2(0); w2(1);
w2(0); for (i = 0; i < count / 2; i++)
WR(4,8); w4w(((u16 *)buf)[i]);
break; w2(0);
WR(4, 8);
case 4: WR(4,0x48); break;
w0(0x40); w2(9); w2(0); w2(1);
for (i=0;i<count/4;i++) w4l(((u32 *)buf)[i]); case 4:
w2(0); WR(4, 0x48);
WR(4,8); w0(0x40); w2(9); w2(0); w2(1);
break; 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) static void bpck_read_block(struct pi_adapter *pi, char *buf, int count)
{
{ int i, l, h; int i, l, h;
switch (pi->mode) { switch (pi->mode) {
case 0: WR(4,0x40); case 0:
WR(4, 0x40);
w0(0x40); t2(2); w0(0x40); t2(2);
for (i=0;i<count;i++) { for (i = 0; i < count; i++) {
t2(4); l = r1(); t2(4); l = r1();
t2(4); h = r1(); t2(4); h = r1();
buf[i] = j44(l,h); buf[i] = j44(l, h);
} }
WR(4,0); WR(4, 0);
break; break;
case 1: WR(4,0x50); case 1:
WR(4, 0x50);
w0(0x40); t2(2); t2(0x20); w0(0x40); t2(2); t2(0x20);
for(i=0;i<count;i++) { t2(4); buf[i] = r0(); } for (i = 0; i < count; i++) {
t2(1); t2(0x20); t2(4);
WR(4,0x10); buf[i] = r0();
}
t2(1); t2(0x20);
WR(4, 0x10);
break; break;
case 2: WR(4,0x48); case 2:
WR(4, 0x48);
w0(0x40); w2(9); w2(0); w2(0x20); 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); w2(0);
WR(4,8); WR(4, 8);
break; break;
case 3: WR(4,0x48); case 3:
w0(0x40); w2(9); w2(0); w2(0x20); WR(4, 0x48);
for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w(); w0(0x40); w2(9); w2(0); w2(0x20);
w2(0); for (i = 0; i < count / 2; i++)
WR(4,8); ((u16 *)buf)[i] = r4w();
break; w2(0);
WR(4, 8);
break;
case 4: WR(4,0x48); case 4:
w0(0x40); w2(9); w2(0); w2(0x20); WR(4, 0x48);
for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l(); w0(0x40); w2(9); w2(0); w2(0x20);
w2(0); for (i = 0; i < count / 4; i++)
WR(4,8); ((u32 *)buf)[i] = r4l();
break; w2(0);
WR(4, 8);
break;
} }
} }
static int bpck_probe_unit(struct pi_adapter *pi) static int bpck_probe_unit(struct pi_adapter *pi)
{
{ int o1, o0, f7, id; int o1, o0, f7, id;
int t, s; int t, s;
id = pi->unit; id = pi->unit;
s = 0; s = 0;
w2(4); w2(0xe); r2(); t2(2); w2(4); w2(0xe); r2(); t2(2);
o1 = r1()&0xf8; o1 = r1()&0xf8;
o0 = r0(); o0 = r0();
w0(255-id); w2(4); w0(id); w0(255-id); w2(4); w0(id);
t2(8); t2(8); t2(8); t2(8); t2(8); t2(8);
t2(2); t = r1()&0xf8; t2(2); t = r1()&0xf8;
f7 = ((id % 8) == 7); 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))) { if ((t == o1) && ((!f7) || (s == o1))) {
w2(0x4c); w0(o0); w2(0x4c); w0(o0);
return 0; return 0;
} }
t2(8); w0(0); t2(2); w2(0x4c); w0(o0); t2(8); w0(0); t2(2); w2(0x4c); w0(o0);
return 1; return 1;
} }
static void bpck_connect(struct pi_adapter *pi) 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); 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); t2(2); t2(2);
switch (pi->mode) { switch (pi->mode) {
case 0:
case 0: t2(8); WR(4,0); t2(8); WR(4, 0);
break; break;
case 1:
case 1: t2(8); WR(4,0x10); t2(8); WR(4, 0x10);
break; break;
case 2: case 2:
case 3: case 3:
case 4: w2(0); WR(4,8); case 4:
w2(0); WR(4, 8);
break; break;
} }
WR(5,8); WR(5,8);
/* if (pi->devtype == PI_PCD) { possibly wrong, purpose unknown */ /*
WR(0x46,0x10); /* fiddle with ESS logic ??? */ * Possibly wrong, purpose unknown (fiddle with ESS logic ???)
WR(0x4c,0x38); * if (pi->devtype == PI_PCD) {
WR(0x4d,0x88); */
WR(0x46,0xa0); WR(0x46, 0x10);
WR(0x41,0); WR(0x4c, 0x38);
WR(0x4e,8); WR(0x4d, 0x88);
/* }*/ WR(0x46, 0xa0);
WR(0x41, 0);
WR(0x4e, 8);
/* } */
} }
static void bpck_disconnect(struct pi_adapter *pi) static void bpck_disconnect(struct pi_adapter *pi)
{
{ w0(0); w0(0);
if (pi->mode >= 2) { w2(9); w2(0); } else t2(2); if (pi->mode >= 2) {
w2(9); w2(0);
} else {
t2(2);
}
w2(0x4c); w0(pi->saved_r0); w2(0x4c); w0(pi->saved_r0);
} }
static void bpck_force_spp(struct pi_adapter *pi) 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 ... */ w2(0);
w0(4); w2(9); w2(0);
{ pi->saved_r0 = r0(); w0(0); w2(1); w2(3); w2(0);
w0(0xff-pi->unit); w2(4); w0(pi->unit); w0(0); w2(9); w2(0);
t2(8); t2(8); t2(8); w2(0x4c); w0(pi->saved_r0);
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);
} }
#define TEST_LEN 16 #define TEST_LEN 16
static int bpck_test_proto(struct pi_adapter *pi) 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]; char buf[TEST_LEN];
bpck_force_spp(pi); bpck_force_spp(pi);
switch (pi->mode) { switch (pi->mode) {
case 0: bpck_connect(pi); case 0:
WR(0x13,0x7f); bpck_connect(pi);
WR(0x13, 0x7f);
w0(0x13); t2(2); w0(0x13); t2(2);
for(i=0;i<TEST_LEN;i++) { for (i = 0; i < TEST_LEN; i++) {
t2(4); l = r1(); t2(4); l = r1();
t2(4); h = r1(); t2(4); h = r1();
buf[i] = j44(l,h); buf[i] = j44(l, h);
} }
bpck_disconnect(pi); bpck_disconnect(pi);
break; break;
case 1: bpck_connect(pi); case 1:
WR(0x13,0x7f); bpck_connect(pi);
w0(0x13); t2(2); t2(0x20); WR(0x13, 0x7f);
for(i=0;i<TEST_LEN;i++) { t2(4); buf[i] = r0(); } w0(0x13); t2(2); t2(0x20);
t2(1); t2(0x20); for (i = 0; i < TEST_LEN; i++) {
t2(4);
buf[i] = r0();
}
t2(1); t2(0x20);
bpck_disconnect(pi); bpck_disconnect(pi);
break; break;
case 2: case 2:
case 3: case 3:
case 4: om = pi->mode; case 4:
om = pi->mode;
pi->mode = 0; pi->mode = 0;
bpck_connect(pi); bpck_connect(pi);
WR(7,3); WR(7, 3);
WR(4,8); WR(4, 8);
bpck_disconnect(pi); bpck_disconnect(pi);
pi->mode = om; 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); w0(0x13); w2(9); w2(1); w0(0); w2(3); w2(0); w2(0xe0);
switch (pi->mode) { switch (pi->mode) {
case 2: for (i=0;i<TEST_LEN;i++) buf[i] = r4(); case 2:
break; for (i = 0; i < TEST_LEN; i++)
case 3: for (i=0;i<TEST_LEN/2;i++) ((u16 *)buf)[i] = r4w(); buf[i] = r4();
break; break;
case 4: for (i=0;i<TEST_LEN/4;i++) ((u32 *)buf)[i] = r4l(); case 3:
break; 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); w2(0);
WR(7,0); WR(7, 0);
bpck_disconnect(pi); bpck_disconnect(pi);
break; break;
} }
dev_dbg(&pi->dev, "bpck: 0x%x unit %d mode %d: ", dev_dbg(&pi->dev, "bpck: 0x%x unit %d mode %d: ",
pi->port, pi->unit, pi->mode); 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; 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; return e;
} }
static void bpck_read_eeprom(struct pi_adapter *pi, char *buf) 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); 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; pi->mode = 0; pi->delay = 6;
bpck_connect(pi); bpck_connect(pi);
WR(4,0); WR(4, 0);
for (i=0;i<64;i++) { for (i = 0; i < 64; i++) {
WR(6,8); WR(6, 8);
WR(6,0xc); WR(6, 0xc);
p = 0x100; p = 0x100;
for (k=0;k<9;k++) { for (k = 0; k < 9; k++) {
f = (((i + 0x180) & p) != 0) * 2; f = (((i + 0x180) & p) != 0) * 2;
WR(6,f+0xc); WR(6, f + 0xc);
WR(6,f+0xd); WR(6, f + 0xd);
WR(6,f+0xc); WR(6, f + 0xc);
p = (p >> 1); p = (p >> 1);
} }
for (j=0;j<2;j++) { for (j = 0; j < 2; j++) {
v = 0; v = 0;
for (k=0;k<8;k++) { for (k = 0; k < 8; k++) {
WR(6,0xc); WR(6, 0xc);
WR(6,0xd); WR(6, 0xd);
WR(6,0xc); WR(6, 0xc);
f = RR(0); f = RR(0);
v = 2*v + (f == 0x84); v = 2 * v + (f == 0x84);
}
buf[2 * i + 1 - j] = v;
} }
buf[2*i+1-j] = v;
}
} }
WR(6,8); WR(6, 8);
WR(6,0); WR(6, 0);
WR(5,8); WR(5, 8);
bpck_disconnect(pi); bpck_disconnect(pi);
if (om >= 2) { if (om >= 2) {
bpck_connect(pi); bpck_connect(pi);
WR(7,3); WR(7, 3);
WR(4,8); WR(4, 8);
bpck_disconnect(pi); bpck_disconnect(pi);
} }
pi->mode = om; pi->delay = od; pi->mode = om; pi->delay = od;
} }
static int bpck_test_port(struct pi_adapter *pi) /* check for 8-bit port */ static int bpck_test_port(struct pi_adapter *pi)
{
{ int i, r, m; int i, r, m;
/* Check for 8-bit port */
w2(0x2c); i = r0(); w0(255-i); r = r0(); w0(i); w2(0x2c); i = r0(); w0(255-i); r = r0(); w0(i);
m = -1; m = -1;
if (r == i) m = 2; if (r == i)
if (r == (255-i)) m = 0; m = 2;
if (r == (255-i))
m = 0;
w2(0xc); i = r0(); w0(255-i); r = r0(); w0(i); w2(0xc);
if (r != (255-i)) m = -1; i = r0();
w0(255-i);
if (m == 0) { w2(6); w2(0xc); r = r0(); w0(0xaa); w0(r); w0(0xaa); } r = r0();
if (m == 2) { w2(0x26); w2(0xc); } 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; return 5;
} }
static void bpck_log_adapter(struct pi_adapter *pi) static void bpck_log_adapter(struct pi_adapter *pi)
{
{ char *mode_string[5] = { "4-bit","8-bit","EPP-8", char *mode_str[5] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" };
"EPP-16","EPP-32" };
char scratch[128]; char scratch[128];
bpck_read_eeprom(pi,scratch); bpck_read_eeprom(pi,scratch);
print_hex_dump_bytes("bpck EEPROM: ", DUMP_PREFIX_NONE, scratch, 128); 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, &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 = { 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. * (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.c is a low-level protocol driver for the Micro Solutions * "BACKPACK" parallel port IDE adapter (works on Series 6 drives).
"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)
Written by: Ken Hahn (linux-dev@micro-solutions.com) */
Clive Turvey (linux-dev@micro-solutions.com)
*/
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
@ -326,11 +324,14 @@ static int bpck6_open(struct pi_adapter *pi)
if (j != k) if (j != k)
goto fail; goto fail;
if (i & 4) // EPP if (i & 4) {
/* EPP */
parport_frob_control(pi->pardev->port, parport_frob_control(pi->pardev->port,
PARPORT_CONTROL_SELECT | PARPORT_CONTROL_INIT, 0); PARPORT_CONTROL_SELECT | PARPORT_CONTROL_INIT, 0);
else // PPC/ECP } else {
/* PPC/ECP */
parport_frob_control(pi->pardev->port, PARPORT_CONTROL_SELECT, 0); parport_frob_control(pi->pardev->port, PARPORT_CONTROL_SELECT, 0);
}
pi->private = 0; pi->private = 0;
@ -347,17 +348,20 @@ fail:
parport_write_control(pi->pardev->port, pi->saved_r2); parport_write_control(pi->pardev->port, pi->saved_r2);
parport_write_data(pi->pardev->port, pi->saved_r0); parport_write_data(pi->pardev->port, pi->saved_r0);
return 0; // FAIL return 0;
} }
static void bpck6_deselect(struct pi_adapter *pi) 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_frob_control(pi->pardev->port, PARPORT_CONTROL_INIT,
PARPORT_CONTROL_INIT); PARPORT_CONTROL_INIT);
else // PPC/ECP } else {
/* PPC/ECP */
parport_frob_control(pi->pardev->port, PARPORT_CONTROL_SELECT, 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_data(pi->pardev->port, pi->saved_r0);
parport_write_control(pi->pardev->port, parport_write_control(pi->pardev->port,
@ -386,7 +390,8 @@ static void bpck6_disconnect(struct pi_adapter *pi)
bpck6_deselect(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", dev_dbg(&pi->dev, "PARPORT indicates modes=%x for lp=0x%lx\n",
pi->pardev->port->modes, pi->pardev->port->base); 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); dev_dbg(&pi->dev, "ppc_open returned %2x\n", out);
if(out) if (out) {
{
bpck6_deselect(pi); bpck6_deselect(pi);
dev_dbg(&pi->dev, "leaving probe\n"); dev_dbg(&pi->dev, "leaving probe\n");
pi->mode = saved_mode; pi->mode = saved_mode;
return(1); return 1;
} }
else
{ dev_dbg(&pi->dev, "Failed open\n");
dev_dbg(&pi->dev, "Failed open\n"); pi->mode = saved_mode;
pi->mode = saved_mode;
return(0); return 0;
}
} }
static void bpck6_log_adapter(struct pi_adapter *pi) static void bpck6_log_adapter(struct pi_adapter *pi)
{ {
char *mode_string[5]= char *mode_string[5] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" };
{"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", dev_info(&pi->dev,
pi->unit, pi->port, pi->mode, mode_string[pi->mode], pi->delay); "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 = { static struct pi_protocol bpck6 = {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,17 +1,15 @@
/* // SPDX-License-Identifier: GPL-2.0-or-later
frpw.c (c) 1996-8 Grant R. Guenther <grant@torque.net> /*
Under the terms of the GNU General Public License * (c) 1996-1998 Grant R. Guenther <grant@torque.net>
*
frpw.c is a low-level protocol driver for the Freecom "Power" * frpw.c is a low-level protocol driver for the Freecom "Power" parallel port
parallel port IDE adapter. * IDE adapter.
*
Some applications of this adapter may require a "printer" reset * Some applications of this adapter may require a "printer" reset prior to
prior to loading the driver. This can be done by loading and * loading the driver. This can be done by loading and unloading the "lp"
unloading the "lp" driver, or it can be done by this driver * driver, or it can be done by this driver if you define FRPW_HARD_RESET.
if you define FRPW_HARD_RESET. The latter is not recommended * The latter is not recommended as it may upset devices on other ports.
as it may upset devices on other ports. */
*/
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.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 cec4 w2(0xc);w2(0xe);w2(0xe);w2(0xc);w2(4);w2(4);w2(4);
#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 * cont = 0 - access the IDE register file
*/ * cont = 1 - access the IDE command set
*/
static int cont_map[2] = { 0x08, 0x10 }; static int cont_map[2] = { 0x08, 0x10 };
static int frpw_read_regr(struct pi_adapter *pi, int cont, int regr) 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]; 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; w0(r); cec4;
w2(6); l = r1(); w2(6); l = r1();
w2(4); h = r1(); w2(4); h = r1();
w2(4); w2(4);
return j44(l,h);
return j44(l, h);
} }
static void frpw_write_regr(struct pi_adapter *pi, int cont, int regr, int val) static void frpw_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{
int r = regr + cont_map[cont];
{ int r; w2(4); w0(r); cec4;
r = regr + cont_map[cont];
w2(4); w0(r); cec4;
w0(val); 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) static void frpw_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: 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) {
switch (pi->mode) {
case 0: case 0:
case 1: w2(4); w0(regr); cec4;
case 2: w2(4); w0(8); cec4; w2(5); for (k = 0; k < count; k++) {
for (k=0;k<count;k++) { w2(6); l = r1();
w0(buf[k]); w2(4); h = r1();
w2(7);w2(5); buf[k] = j44(l, h);
} }
w2(4); w2(4);
break; break;
case 3: w2(4); w0(0xc8); cec4; w2(5); case 1:
for (k=0;k<count;k++) w4(buf[k]); 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); w2(4);
break; break;
case 4: w2(4); w0(0xc8); cec4; w2(5); case 3:
for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]); w2(4); w0(regr + 0x80); cec4;
w2(4); for (k = 0; k < count - 2; k++)
break; 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); case 4:
for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]); w2(4); w0(regr + 0x80); cec4;
w2(4); for (k = 0; k < count / 2 - 1; k++)
break; ((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) static void frpw_connect(struct pi_adapter *pi)
{
{ pi->saved_r0 = r0(); pi->saved_r0 = r0();
pi->saved_r2 = r2(); pi->saved_r2 = r2();
w2(4); w2(4);
} }
static void frpw_disconnect(struct pi_adapter *pi) static void frpw_disconnect(struct pi_adapter *pi)
{
{ w2(4); w0(0x20); cec4; w2(4); w0(0x20); cec4;
w0(pi->saved_r0); w0(pi->saved_r0);
w2(pi->saved_r2); 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.
*/
/*
* 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) 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 #ifdef FRPW_HARD_RESET
w0(0); w2(8); udelay(50); w2(0xc); /* parallel bus 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_r0 = r0();
pi->saved_r2 = r2(); pi->saved_r2 = r2();
w2(4); w0(4); w2(6); w2(7); w2(4); w0(4); w2(6); w2(7);
a = r1() & 0xff; w2(4); b = r1() & 0xff; a = r1() & 0xff; w2(4); b = r1() & 0xff;
w2(0xc); w2(0xe); w2(4); w2(0xc); w2(0xe); w2(4);
@ -200,65 +209,70 @@ static int frpw_test_pnp(struct pi_adapter *pi)
w0(pi->saved_r0); w0(pi->saved_r0);
w2(pi->saved_r2); w2(pi->saved_r2);
return ((~a&0x40) && (b&0x40)); 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]));
} }
/*
* 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) 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", dev_info(&pi->dev,
((pi->private % 2) == 0) ? "Xilinx" : "ASIC", "Freecom (%s) adapter at 0x%x, mode %d (%s), delay %d\n",
pi->port, pi->mode, mode_string[pi->mode], pi->delay); ((pi->private & 0x1) == 0) ? "Xilinx" : "ASIC",
pi->port, pi->mode, mode[pi->mode], pi->delay);
} }
static struct pi_protocol frpw = { 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> * (c) 1997-1998 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
This is a low-level driver for the KBIC-951A and KBIC-971A * parallel to IDE adapter chips from KingByte Information Systems.
parallel to IDE adapter chips from KingByte Information Systems. *
* The chips are almost identical, however, the wakeup code
The chips are almost identical, however, the wakeup code * required for the 971A interferes with the correct operation of
required for the 971A interferes with the correct operation of * the 951A, so this driver registers itself twice, once for
the 951A, so this driver registers itself twice, once for * each chip.
each chip. */
*/
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
@ -21,212 +20,223 @@
#include <asm/io.h> #include <asm/io.h>
#include "pata_parport.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 j44(a, b) ((((a >> 4) & 0x0f) | (b & 0xf0)) ^ 0x88)
#define j53(w) (((w>>3)&0x1f)|((w>>4)&0xe0)) #define j53(w) (((w >> 3) & 0x1f) | ((w >> 4) & 0xe0))
/* 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] = { 0x80, 0x40 }; static int cont_map[2] = { 0x80, 0x40 };
static int kbic_read_regr(struct pi_adapter *pi, int cont, int regr) 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) { switch (pi->mode) {
case 0:
case 0: w0(regr|0x18|s); w2(4); w2(6); w2(4); w2(1); w0(8); w0(regr | 0x18 | s); w2(4); w2(6); w2(4); w2(1); w0(8);
a = r1(); w0(0x28); b = r1(); w2(4); a = r1(); w0(0x28); b = r1(); w2(4);
return j44(a,b); return j44(a, b);
case 1:
case 1: w0(regr|0x38|s); w2(4); w2(6); w2(4); w2(5); w0(8); w0(regr|0x38 | s); w2(4); w2(6); w2(4); w2(5); w0(8);
a = r12w(); w2(4); a = r12w(); w2(4);
return j53(a); return j53(a);
case 2:
case 2: w0(regr|0x08|s); w2(4); w2(6); w2(4); w2(0xa5); w2(0xa1); w0(regr | 0x08 | s); w2(4); w2(6); w2(4); w2(0xa5); w2(0xa1);
a = r0(); w2(4); a = r0(); w2(4);
return a; return a;
case 3: case 3:
case 4: 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); a = r4(); b = r4(); w2(4); w2(0); w2(4);
return a; return a;
} }
return -1; return -1;
} }
static void kbic_write_regr(struct pi_adapter *pi, int cont, int regr, int val) static void kbic_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
{
int s = cont_map[cont];
{ int s; switch (pi->mode) {
case 0:
s = cont_map[cont]; case 1:
case 2:
switch (pi->mode) { w0(regr | 0x10 | s); w2(4); w2(6); w2(4);
case 0:
case 1:
case 2: w0(regr|0x10|s); w2(4); w2(6); w2(4);
w0(val); w2(5); w2(4); w0(val); w2(5); w2(4);
break; break;
case 3: case 3:
case 4: 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); w4(val); w4(val);
w2(4); w2(0); w2(4); w2(4); w2(0); w2(4);
break; break;
} }
} }
static void k951_connect(struct pi_adapter *pi) static void k951_connect(struct pi_adapter *pi)
{
{ pi->saved_r0 = r0(); pi->saved_r0 = r0();
pi->saved_r2 = r2(); pi->saved_r2 = r2();
w2(4); w2(4);
} }
static void k951_disconnect(struct pi_adapter *pi) static void k951_disconnect(struct pi_adapter *pi)
{
{ w0(pi->saved_r0); w0(pi->saved_r0);
w2(pi->saved_r2); w2(pi->saved_r2);
} }
#define CCP(x) w2(0xc4);w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);\ #define CCP(x) \
w0(0x78);w0(x);w2(0xc5);w2(0xc4);w0(0xff); 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) static void k971_connect(struct pi_adapter *pi)
{
{ pi->saved_r0 = r0(); pi->saved_r0 = r0();
pi->saved_r2 = r2(); pi->saved_r2 = r2();
CCP(0x20); CCP(0x20);
w2(4); w2(4);
} }
static void k971_disconnect(struct pi_adapter *pi) static void k971_disconnect(struct pi_adapter *pi)
{
{ CCP(0x30); CCP(0x30);
w0(pi->saved_r0); 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) 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:
switch (pi->mode) { w0(0x98); w2(4); w2(6); w2(4);
for (k = 0; k < count / 2; k++) {
case 0: w0(0x98); w2(4); w2(6); w2(4); w2(1); w0(8);
for (k=0;k<count/2;k++) { a = r1();
w2(1); w0(8); a = r1(); w0(0x28);
w0(0x28); b = r1(); b = r1();
buf[2*k] = j44(a,b); buf[2 * k] = j44(a, b);
w2(5); b = r1(); w2(5);
w0(8); a = r1(); b = r1();
buf[2*k+1] = j44(a,b); w0(8);
a = r1();
buf[2 * k + 1] = j44(a, b);
w2(4); w2(4);
} }
break; break;
case 1:
case 1: w0(0xb8); w2(4); w2(6); w2(4); w0(0xb8); w2(4); w2(6); w2(4);
for (k=0;k<count/4;k++) { for (k = 0; k < count / 4; k++) {
w0(0xb8); w0(0xb8);
w2(4); w2(5);
w0(8); buf[4*k] = j53(r12w());
w0(0xb8); buf[4*k+1] = j53(r12w());
w2(4); w2(5); w2(4); w2(5);
buf[4*k+3] = j53(r12w()); w0(8);
w0(8); buf[4*k+2] = j53(r12w()); buf[4 * k] = j53(r12w());
} w0(0xb8);
w2(4); buf[4 * k + 1] = j53(r12w());
break; w2(4); w2(5);
buf[4 * k + 3] = j53(r12w());
case 2: w0(0x88); w2(4); w2(6); w2(4); w0(8);
for (k=0;k<count/2;k++) { buf[4 * k + 2] = j53(r12w());
w2(0xa0); w2(0xa1); buf[2*k] = r0(); }
w2(0xa5); buf[2*k+1] = r0(); w2(4);
} break;
w2(4); case 2:
break; w0(0x88); w2(4); w2(6); w2(4);
for (k = 0; k < count / 2; k++) {
case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0); w2(0xa0); w2(0xa1);
for (k=0;k<count;k++) buf[k] = r4(); buf[2 * k] = r0();
w2(4); w2(0); w2(4); w2(0xa5);
break; buf[2 * k + 1] = r0();
}
case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0); w2(4);
for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w(); break;
w2(4); w2(0); w2(4); case 3:
break; w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for (k = 0; k < count; k++)
case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0); buf[k] = r4();
for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l(); w2(4); w2(0); w2(4);
w2(4); w2(0); w2(4); break;
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) static void kbic_write_block(struct pi_adapter *pi, char *buf, int count)
{
int k;
{ int k; switch (pi->mode) {
case 0:
switch (pi->mode) { case 1:
case 2:
case 0: w0(0x90); w2(4); w2(6); w2(4);
case 1: for (k = 0; k < count / 2; k++) {
case 2: w0(0x90); w2(4); w2(6); w2(4); w0(buf[2 * k + 1]);
for(k=0;k<count/2;k++) { w2(0); w2(4);
w0(buf[2*k+1]); w2(0); w2(4); w0(buf[2 * k]);
w0(buf[2*k]); w2(5); w2(4); w2(5); w2(4);
} }
break; break;
case 3:
case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0); w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for(k=0;k<count/2;k++) { for (k = 0; k < count / 2; k++) {
w4(buf[2*k+1]); w4(buf[2 * k + 1]);
w4(buf[2*k]); w4(buf[2 * k]);
} }
w2(4); w2(0); w2(4); w2(4); w2(0); w2(4);
break; break;
case 4:
case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0); w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for (k = 0; k < count / 2; k++) for (k = 0; k < count / 2; k++)
w4w(swab16(((u16 *)buf)[k])); w4w(swab16(((u16 *)buf)[k]));
w2(4); w2(0); w2(4); w2(4); w2(0); w2(4);
break; break;
case 5:
case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0); w0(0xa0); w2(4); w2(6); w2(4); w3(0);
for (k = 0; k < count / 4; k++) for (k = 0; k < count / 4; k++)
w4l(swab16(((u16 *)buf)[2 * k]) | w4l(swab16(((u16 *)buf)[2 * k]) |
swab16(((u16 *)buf)[2 * k + 1]) << 16); swab16(((u16 *)buf)[2 * k + 1]) << 16);
w2(4); w2(0); w2(4); w2(4); w2(0); w2(4);
break; break;
}
}
} }
static void kbic_log_adapter(struct pi_adapter *pi, char *chip) static void kbic_log_adapter(struct pi_adapter *pi, char *chip)
{
{ char *mode_string[6] = {"4-bit","5/3","8-bit", char *mode[6] = { "4-bit", "5/3", "8-bit", "EPP-8", "EPP_16", "EPP-32"};
"EPP-8","EPP_16","EPP-32"};
dev_info(&pi->dev, "KingByte %s at 0x%x, mode %d (%s), delay %d\n", 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) static void k951_log_adapter(struct pi_adapter *pi)

View File

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

View File

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

View File

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

View File

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

View File

@ -32,6 +32,7 @@
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <linux/libata.h> #include <linux/libata.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h>
#define DRV_NAME "sata_svw" #define DRV_NAME "sata_svw"
#define DRV_VERSION "2.3" #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 */ /* Match it to a port node */
index = (ap == ap->host->ports[0]) ? 0 : 1; index = (ap == ap->host->ports[0]) ? 0 : 1;
for (np = np->child; np != NULL; np = np->sibling) { for (np = np->child; np != NULL; np = np->sibling) {
const u32 *reg = of_get_property(np, "reg", NULL); u64 reg;
if (!reg)
if (of_property_read_reg(np, 0, &reg, NULL))
continue; continue;
if (index == *reg) { if (index == reg) {
seq_printf(m, "devspec: %pOF\n", np); seq_printf(m, "devspec: %pOF\n", np);
break; 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); struct domain_device *dev = sdev_to_domain_dev(sdev);
if (dev_is_sata(dev)) if (dev_is_sata(dev))
return ata_change_queue_depth(dev->sata_dev.ap, return ata_change_queue_depth(dev->sata_dev.ap, sdev, depth);
sas_to_ata_dev(dev), sdev, depth);
if (!sdev->tagged_supported) if (!sdev->tagged_supported)
depth = 1; 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 void ata_scsi_slave_destroy(struct scsi_device *sdev);
extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
int queue_depth); int queue_depth);
extern int ata_change_queue_depth(struct ata_port *ap, struct ata_device *dev, extern int ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev,
struct scsi_device *sdev, int queue_depth); int queue_depth);
extern struct ata_device *ata_dev_pair(struct ata_device *adev); 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 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); 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; 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 * ACPI - drivers/ata/libata-acpi.c