drivers/block: Move PARIDE protocol modules to drivers/ata/pata_parport
authorOndrej Zary <linux@zary.sk>
Mon, 30 Jan 2023 21:10:50 +0000 (22:10 +0100)
committerDamien Le Moal <damien.lemoal@opensource.wdc.com>
Tue, 31 Jan 2023 11:30:49 +0000 (20:30 +0900)
Move PARIDE protocol modules out of drivers/block into
drivers/ata/pata_parport and update the CONFIG_ symbol names to
PATA_PARPORT.

[Damien]
The pata_parport driver file itsef is also moved together with the
protocol modules in drivers/ata/pata_parport.

Signed-off-by: Ondrej Zary <linux@zary.sk>
Acked-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
42 files changed:
drivers/Makefile
drivers/ata/Kconfig
drivers/ata/Makefile
drivers/ata/pata_parport.c [deleted file]
drivers/ata/pata_parport/Kconfig [new file with mode: 0644]
drivers/ata/pata_parport/Makefile [new file with mode: 0644]
drivers/ata/pata_parport/aten.c [new file with mode: 0644]
drivers/ata/pata_parport/bpck.c [new file with mode: 0644]
drivers/ata/pata_parport/bpck6.c [new file with mode: 0644]
drivers/ata/pata_parport/comm.c [new file with mode: 0644]
drivers/ata/pata_parport/dstr.c [new file with mode: 0644]
drivers/ata/pata_parport/epat.c [new file with mode: 0644]
drivers/ata/pata_parport/epia.c [new file with mode: 0644]
drivers/ata/pata_parport/fit2.c [new file with mode: 0644]
drivers/ata/pata_parport/fit3.c [new file with mode: 0644]
drivers/ata/pata_parport/friq.c [new file with mode: 0644]
drivers/ata/pata_parport/frpw.c [new file with mode: 0644]
drivers/ata/pata_parport/kbic.c [new file with mode: 0644]
drivers/ata/pata_parport/ktti.c [new file with mode: 0644]
drivers/ata/pata_parport/on20.c [new file with mode: 0644]
drivers/ata/pata_parport/on26.c [new file with mode: 0644]
drivers/ata/pata_parport/pata_parport.c [new file with mode: 0644]
drivers/ata/pata_parport/ppc6lnx.c [new file with mode: 0644]
drivers/block/Kconfig
drivers/block/paride/Kconfig [deleted file]
drivers/block/paride/Makefile [deleted file]
drivers/block/paride/aten.c [deleted file]
drivers/block/paride/bpck.c [deleted file]
drivers/block/paride/bpck6.c [deleted file]
drivers/block/paride/comm.c [deleted file]
drivers/block/paride/dstr.c [deleted file]
drivers/block/paride/epat.c [deleted file]
drivers/block/paride/epia.c [deleted file]
drivers/block/paride/fit2.c [deleted file]
drivers/block/paride/fit3.c [deleted file]
drivers/block/paride/friq.c [deleted file]
drivers/block/paride/frpw.c [deleted file]
drivers/block/paride/kbic.c [deleted file]
drivers/block/paride/ktti.c [deleted file]
drivers/block/paride/on20.c [deleted file]
drivers/block/paride/on26.c [deleted file]
drivers/block/paride/ppc6lnx.c [deleted file]

index f1365608bc8c39d3205c4a1feb439b777291152b..788e37269ee9d0d449b21057bf3c29d694ae6302 100644 (file)
@@ -98,7 +98,6 @@ obj-$(CONFIG_DIO)             += dio/
 obj-$(CONFIG_SBUS)             += sbus/
 obj-$(CONFIG_ZORRO)            += zorro/
 obj-$(CONFIG_ATA_OVER_ETH)     += block/aoe/
-obj-y                          += block/paride/
 obj-$(CONFIG_TC)               += tc/
 obj-$(CONFIG_USB_PHY)          += usb/
 obj-$(CONFIG_USB)              += usb/
index a5a31ba34bd3f920f6bca346b0967f1ac2f6c8d6..2fa9e66ba824b74722741320b355695a55d84a58 100644 (file)
@@ -1174,7 +1174,7 @@ config PATA_PARPORT
          Read <file:Documentation/admin-guide/blockdev/paride.rst> for more
          information.
 
-         Use the old PARIDE protocol modules.
+source "drivers/ata/pata_parport/Kconfig"
 
 comment "Generic fallback / legacy drivers"
 
index 23588738cff0bd8e4e27fb0008eed98fa09f6e76..d846159123875a02dc6c51e3be0ab919b892a36a 100644 (file)
@@ -114,7 +114,7 @@ obj-$(CONFIG_PATA_SAMSUNG_CF)       += pata_samsung_cf.o
 
 obj-$(CONFIG_PATA_PXA)         += pata_pxa.o
 
-obj-$(CONFIG_PATA_PARPORT)     += pata_parport.o
+obj-$(CONFIG_PATA_PARPORT)     += pata_parport/
 
 # Should be last but two libata driver
 obj-$(CONFIG_PATA_ACPI)                += pata_acpi.o
diff --git a/drivers/ata/pata_parport.c b/drivers/ata/pata_parport.c
deleted file mode 100644 (file)
index 9e8ad93..0000000
+++ /dev/null
@@ -1,759 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright 2023 Ondrej Zary
- * based on paride.c by Grant R. Guenther <grant@torque.net>
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/parport.h>
-#include <linux/pata_parport.h>
-
-#define DRV_NAME "pata_parport"
-
-static DEFINE_IDR(parport_list);
-static DEFINE_IDR(protocols);
-static DEFINE_IDA(pata_parport_bus_dev_ids);
-static DEFINE_MUTEX(pi_mutex);
-
-static bool probe = true;
-module_param(probe, bool, 0644);
-MODULE_PARM_DESC(probe, "Enable automatic device probing (0=off, 1=on [default])");
-
-/*
- * libata drivers cannot sleep so this driver claims parport before activating
- * the ata host and keeps it claimed (and protocol connected) until the ata
- * host is removed. Unfortunately, this means that you cannot use any chained
- * devices (neither other pata_parport devices nor a printer).
- */
-static void pi_connect(struct pi_adapter *pi)
-{
-       parport_claim_or_block(pi->pardev);
-       pi->proto->connect(pi);
-}
-
-static void pi_disconnect(struct pi_adapter *pi)
-{
-       pi->proto->disconnect(pi);
-       parport_release(pi->pardev);
-}
-
-static void pata_parport_dev_select(struct ata_port *ap, unsigned int device)
-{
-       struct pi_adapter *pi = ap->host->private_data;
-       u8 tmp;
-
-       if (device == 0)
-               tmp = ATA_DEVICE_OBS;
-       else
-               tmp = ATA_DEVICE_OBS | ATA_DEV1;
-
-       pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tmp);
-       ata_sff_pause(ap);
-}
-
-static bool pata_parport_devchk(struct ata_port *ap, unsigned int device)
-{
-       struct pi_adapter *pi = ap->host->private_data;
-       u8 nsect, lbal;
-
-       pata_parport_dev_select(ap, device);
-
-       pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0x55);
-       pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
-
-       pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0xaa);
-       pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0x55);
-
-       pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 055);
-       pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
-
-       nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
-       lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
-
-       return (nsect == 0x55) && (lbal == 0xaa);
-}
-
-static int pata_parport_bus_softreset(struct ata_port *ap, unsigned int devmask,
-                                     unsigned long deadline)
-{
-       struct pi_adapter *pi = ap->host->private_data;
-
-       /* software reset.  causes dev0 to be selected */
-       pi->proto->write_regr(pi, 1, 6, ap->ctl);
-       udelay(20);
-       pi->proto->write_regr(pi, 1, 6, ap->ctl | ATA_SRST);
-       udelay(20);
-       pi->proto->write_regr(pi, 1, 6, ap->ctl);
-       ap->last_ctl = ap->ctl;
-
-       /* wait the port to become ready */
-       return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
-}
-
-static int pata_parport_softreset(struct ata_link *link, unsigned int *classes,
-                                 unsigned long deadline)
-{
-       struct ata_port *ap = link->ap;
-       unsigned int devmask = 0;
-       int rc;
-       u8 err;
-
-       /* determine if device 0/1 are present */
-       if (pata_parport_devchk(ap, 0))
-               devmask |= (1 << 0);
-       if (pata_parport_devchk(ap, 1))
-               devmask |= (1 << 1);
-
-       /* select device 0 again */
-       pata_parport_dev_select(ap, 0);
-
-       /* issue bus reset */
-       rc = pata_parport_bus_softreset(ap, devmask, deadline);
-       if (rc && rc != -ENODEV) {
-               ata_link_err(link, "SRST failed (errno=%d)\n", rc);
-               return rc;
-       }
-
-       /* determine by signature whether we have ATA or ATAPI devices */
-       classes[0] = ata_sff_dev_classify(&link->device[0],
-                                         devmask & (1 << 0), &err);
-       if (err != 0x81)
-               classes[1] = ata_sff_dev_classify(&link->device[1],
-                                                 devmask & (1 << 1), &err);
-
-       return 0;
-}
-
-static u8 pata_parport_check_status(struct ata_port *ap)
-{
-       struct pi_adapter *pi = ap->host->private_data;
-
-       return pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
-}
-
-static u8 pata_parport_check_altstatus(struct ata_port *ap)
-{
-       struct pi_adapter *pi = ap->host->private_data;
-
-       return pi->proto->read_regr(pi, 1, 6);
-}
-
-static void pata_parport_tf_load(struct ata_port *ap,
-                                const struct ata_taskfile *tf)
-{
-       struct pi_adapter *pi = ap->host->private_data;
-
-       if (tf->ctl != ap->last_ctl) {
-               pi->proto->write_regr(pi, 1, 6, tf->ctl);
-               ap->last_ctl = tf->ctl;
-               ata_wait_idle(ap);
-       }
-
-       if (tf->flags & ATA_TFLAG_ISADDR) {
-               if (tf->flags & ATA_TFLAG_LBA48) {
-                       pi->proto->write_regr(pi, 0, ATA_REG_FEATURE,
-                                             tf->hob_feature);
-                       pi->proto->write_regr(pi, 0, ATA_REG_NSECT,
-                                             tf->hob_nsect);
-                       pi->proto->write_regr(pi, 0, ATA_REG_LBAL,
-                                             tf->hob_lbal);
-                       pi->proto->write_regr(pi, 0, ATA_REG_LBAM,
-                                             tf->hob_lbam);
-                       pi->proto->write_regr(pi, 0, ATA_REG_LBAH,
-                                             tf->hob_lbah);
-               }
-               pi->proto->write_regr(pi, 0, ATA_REG_FEATURE, tf->feature);
-               pi->proto->write_regr(pi, 0, ATA_REG_NSECT, tf->nsect);
-               pi->proto->write_regr(pi, 0, ATA_REG_LBAL, tf->lbal);
-               pi->proto->write_regr(pi, 0, ATA_REG_LBAM, tf->lbam);
-               pi->proto->write_regr(pi, 0, ATA_REG_LBAH, tf->lbah);
-       }
-
-       if (tf->flags & ATA_TFLAG_DEVICE)
-               pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tf->device);
-
-       ata_wait_idle(ap);
-}
-
-static void pata_parport_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-{
-       struct pi_adapter *pi = ap->host->private_data;
-
-       tf->status = pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
-       tf->error = pi->proto->read_regr(pi, 0, ATA_REG_ERR);
-       tf->nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
-       tf->lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
-       tf->lbam = pi->proto->read_regr(pi, 0, ATA_REG_LBAM);
-       tf->lbah = pi->proto->read_regr(pi, 0, ATA_REG_LBAH);
-       tf->device = pi->proto->read_regr(pi, 0, ATA_REG_DEVICE);
-
-       if (tf->flags & ATA_TFLAG_LBA48) {
-               pi->proto->write_regr(pi, 1, 6, tf->ctl | ATA_HOB);
-               tf->hob_feature = pi->proto->read_regr(pi, 0, ATA_REG_ERR);
-               tf->hob_nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
-               tf->hob_lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
-               tf->hob_lbam = pi->proto->read_regr(pi, 0, ATA_REG_LBAM);
-               tf->hob_lbah = pi->proto->read_regr(pi, 0, ATA_REG_LBAH);
-               pi->proto->write_regr(pi, 1, 6, tf->ctl);
-               ap->last_ctl = tf->ctl;
-       }
-}
-
-static void pata_parport_exec_command(struct ata_port *ap,
-                                     const struct ata_taskfile *tf)
-{
-       struct pi_adapter *pi = ap->host->private_data;
-
-       pi->proto->write_regr(pi, 0, ATA_REG_CMD, tf->command);
-       ata_sff_pause(ap);
-}
-
-static unsigned int pata_parport_data_xfer(struct ata_queued_cmd *qc,
-                               unsigned char *buf, unsigned int buflen, int rw)
-{
-       struct ata_port *ap = qc->dev->link->ap;
-       struct pi_adapter *pi = ap->host->private_data;
-
-       if (rw == READ)
-               pi->proto->read_block(pi, buf, buflen);
-       else
-               pi->proto->write_block(pi, buf, buflen);
-
-       return buflen;
-}
-
-static void pata_parport_drain_fifo(struct ata_queued_cmd *qc)
-{
-       int count;
-       struct ata_port *ap;
-       struct pi_adapter *pi;
-       char junk[2];
-
-       /* We only need to flush incoming data when a command was running */
-       if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
-               return;
-
-       ap = qc->ap;
-       pi = ap->host->private_data;
-       /* Drain up to 64K of data before we give up this recovery method */
-       for (count = 0; (pata_parport_check_status(ap) & ATA_DRQ)
-                                               && count < 65536; count += 2) {
-               pi->proto->read_block(pi, junk, 2);
-       }
-
-       if (count)
-               ata_port_dbg(ap, "drained %d bytes to clear DRQ\n", count);
-}
-
-static struct ata_port_operations pata_parport_port_ops = {
-       .inherits               = &ata_sff_port_ops,
-
-       .softreset              = pata_parport_softreset,
-       .hardreset              = NULL,
-
-       .sff_dev_select         = pata_parport_dev_select,
-       .sff_check_status       = pata_parport_check_status,
-       .sff_check_altstatus    = pata_parport_check_altstatus,
-       .sff_tf_load            = pata_parport_tf_load,
-       .sff_tf_read            = pata_parport_tf_read,
-       .sff_exec_command       = pata_parport_exec_command,
-       .sff_data_xfer          = pata_parport_data_xfer,
-       .sff_drain_fifo         = pata_parport_drain_fifo,
-};
-
-static const struct ata_port_info pata_parport_port_info = {
-       .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_POLLING,
-       .pio_mask       = ATA_PIO0,
-       /* No DMA */
-       .port_ops       = &pata_parport_port_ops,
-};
-
-static void pi_release(struct pi_adapter *pi)
-{
-       parport_unregister_device(pi->pardev);
-       if (pi->proto->release_proto)
-               pi->proto->release_proto(pi);
-       module_put(pi->proto->owner);
-}
-
-static int default_test_proto(struct pi_adapter *pi, char *scratch)
-{
-       int j, k;
-       int e[2] = { 0, 0 };
-
-       pi->proto->connect(pi);
-
-       for (j = 0; j < 2; j++) {
-               pi->proto->write_regr(pi, 0, 6, 0xa0 + j * 0x10);
-               for (k = 0; k < 256; k++) {
-                       pi->proto->write_regr(pi, 0, 2, k ^ 0xaa);
-                       pi->proto->write_regr(pi, 0, 3, k ^ 0x55);
-                       if (pi->proto->read_regr(pi, 0, 2) != (k ^ 0xaa))
-                               e[j]++;
-               }
-       }
-       pi->proto->disconnect(pi);
-
-       dev_dbg(&pi->dev, "%s: port 0x%x, mode %d, test=(%d,%d)\n",
-               pi->proto->name, pi->port, pi->mode, e[0], e[1]);
-
-       return e[0] && e[1];    /* not here if both > 0 */
-}
-
-static int pi_test_proto(struct pi_adapter *pi, char *scratch)
-{
-       int res;
-
-       parport_claim_or_block(pi->pardev);
-       if (pi->proto->test_proto)
-               res = pi->proto->test_proto(pi, scratch, 1);
-       else
-               res = default_test_proto(pi, scratch);
-       parport_release(pi->pardev);
-
-       return res;
-}
-
-static bool pi_probe_mode(struct pi_adapter *pi, int max, char *scratch)
-{
-       int best, range;
-
-       if (pi->mode != -1) {
-               if (pi->mode >= max)
-                       return false;
-               range = 3;
-               if (pi->mode >= pi->proto->epp_first)
-                       range = 8;
-               if (range == 8 && pi->port % 8)
-                       return false;
-               return !pi_test_proto(pi, scratch);
-       }
-       best = -1;
-       for (pi->mode = 0; pi->mode < max; pi->mode++) {
-               range = 3;
-               if (pi->mode >= pi->proto->epp_first)
-                       range = 8;
-               if (range == 8 && pi->port % 8)
-                       break;
-               if (!pi_test_proto(pi, scratch))
-                       best = pi->mode;
-       }
-       pi->mode = best;
-       return best > -1;
-}
-
-static bool pi_probe_unit(struct pi_adapter *pi, int unit, char *scratch)
-{
-       int max, s, e;
-
-       s = unit;
-       e = s + 1;
-
-       if (s == -1) {
-               s = 0;
-               e = pi->proto->max_units;
-       }
-
-       if (pi->proto->test_port) {
-               parport_claim_or_block(pi->pardev);
-               max = pi->proto->test_port(pi);
-               parport_release(pi->pardev);
-       } else {
-               max = pi->proto->max_mode;
-       }
-
-       if (pi->proto->probe_unit) {
-               parport_claim_or_block(pi->pardev);
-               for (pi->unit = s; pi->unit < e; pi->unit++) {
-                       if (pi->proto->probe_unit(pi)) {
-                               parport_release(pi->pardev);
-                               return pi_probe_mode(pi, max, scratch);
-                       }
-               }
-               parport_release(pi->pardev);
-               return false;
-       }
-
-       return pi_probe_mode(pi, max, scratch);
-}
-
-static void pata_parport_dev_release(struct device *dev)
-{
-       struct pi_adapter *pi = container_of(dev, struct pi_adapter, dev);
-
-       kfree(pi);
-}
-
-static void pata_parport_bus_release(struct device *dev)
-{
-       /* nothing to do here but required to avoid warning on device removal */
-}
-
-static struct bus_type pata_parport_bus_type = {
-       .name = DRV_NAME,
-};
-
-static struct device pata_parport_bus = {
-       .init_name = DRV_NAME,
-       .release = pata_parport_bus_release,
-};
-
-static struct scsi_host_template pata_parport_sht = {
-       PATA_PARPORT_SHT("pata_parport")
-};
-
-struct pi_device_match {
-       struct parport *parport;
-       struct pi_protocol *proto;
-};
-
-static int pi_find_dev(struct device *dev, void *data)
-{
-       struct pi_adapter *pi = container_of(dev, struct pi_adapter, dev);
-       struct pi_device_match *match = data;
-
-       return pi->pardev->port == match->parport && pi->proto == match->proto;
-}
-
-static struct pi_adapter *pi_init_one(struct parport *parport,
-                       struct pi_protocol *pr, int mode, int unit, int delay)
-{
-       struct pardev_cb par_cb = { };
-       char scratch[512];
-       const struct ata_port_info *ppi[] = { &pata_parport_port_info };
-       struct ata_host *host;
-       struct pi_adapter *pi;
-       struct pi_device_match match = { .parport = parport, .proto = pr };
-
-       /*
-        * Abort if there's a device already registered on the same parport
-        * using the same protocol.
-        */
-       if (bus_for_each_dev(&pata_parport_bus_type, NULL, &match, pi_find_dev))
-               return NULL;
-
-       pi = kzalloc(sizeof(struct pi_adapter), GFP_KERNEL);
-       if (!pi)
-               return NULL;
-
-       /* set up pi->dev before pi_probe_unit() so it can use dev_printk() */
-       pi->dev.parent = &pata_parport_bus;
-       pi->dev.bus = &pata_parport_bus_type;
-       pi->dev.driver = &pr->driver;
-       pi->dev.release = pata_parport_dev_release;
-       pi->dev.id = ida_alloc(&pata_parport_bus_dev_ids, GFP_KERNEL);
-       if (pi->dev.id < 0)
-               return NULL; /* pata_parport_dev_release will do kfree(pi) */
-       dev_set_name(&pi->dev, "pata_parport.%u", pi->dev.id);
-       if (device_register(&pi->dev)) {
-               put_device(&pi->dev);
-               goto out_ida_free;
-       }
-
-       pi->proto = pr;
-
-       if (!try_module_get(pi->proto->owner))
-               goto out_unreg_dev;
-       if (pi->proto->init_proto && pi->proto->init_proto(pi) < 0)
-               goto out_module_put;
-
-       pi->delay = (delay == -1) ? pi->proto->default_delay : delay;
-       pi->mode = mode;
-       pi->port = parport->base;
-
-       par_cb.private = pi;
-       pi->pardev = parport_register_dev_model(parport, DRV_NAME, &par_cb,
-                                               pi->dev.id);
-       if (!pi->pardev)
-               goto out_module_put;
-
-       if (!pi_probe_unit(pi, unit, scratch)) {
-               dev_info(&pi->dev, "Adapter not found\n");
-               goto out_unreg_parport;
-       }
-
-       pi->proto->log_adapter(pi, scratch, 1);
-
-       host = ata_host_alloc_pinfo(&pi->pardev->dev, ppi, 1);
-       if (!host)
-               goto out_unreg_parport;
-       dev_set_drvdata(&pi->dev, host);
-       host->private_data = pi;
-
-       ata_port_desc(host->ports[0], "port %s", pi->pardev->port->name);
-       ata_port_desc(host->ports[0], "protocol %s", pi->proto->name);
-
-       pi_connect(pi);
-       if (ata_host_activate(host, 0, NULL, 0, &pata_parport_sht))
-               goto out_unreg_parport;
-
-       return pi;
-
-out_unreg_parport:
-       pi_disconnect(pi);
-       parport_unregister_device(pi->pardev);
-       if (pi->proto->release_proto)
-               pi->proto->release_proto(pi);
-out_module_put:
-       module_put(pi->proto->owner);
-out_unreg_dev:
-       device_unregister(&pi->dev);
-out_ida_free:
-       ida_free(&pata_parport_bus_dev_ids, pi->dev.id);
-       return NULL;
-}
-
-int pata_parport_register_driver(struct pi_protocol *pr)
-{
-       int error;
-       struct parport *parport;
-       int port_num;
-
-       pr->driver.bus = &pata_parport_bus_type;
-       pr->driver.name = pr->name;
-       error = driver_register(&pr->driver);
-       if (error)
-               return error;
-
-       mutex_lock(&pi_mutex);
-       error = idr_alloc(&protocols, pr, 0, 0, GFP_KERNEL);
-       if (error < 0) {
-               driver_unregister(&pr->driver);
-               mutex_unlock(&pi_mutex);
-               return error;
-       }
-
-       pr_info("pata_parport: protocol %s registered\n", pr->name);
-
-       if (probe) {
-               /* probe all parports using this protocol */
-               idr_for_each_entry(&parport_list, parport, port_num)
-                       pi_init_one(parport, pr, -1, 0, -1);
-       }
-       mutex_unlock(&pi_mutex);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(pata_parport_register_driver);
-
-void pata_parport_unregister_driver(struct pi_protocol *pr)
-{
-       struct pi_protocol *pr_iter;
-       int id = -1;
-
-       mutex_lock(&pi_mutex);
-       idr_for_each_entry(&protocols, pr_iter, id) {
-               if (pr_iter == pr)
-                       break;
-       }
-       idr_remove(&protocols, id);
-       mutex_unlock(&pi_mutex);
-       driver_unregister(&pr->driver);
-}
-EXPORT_SYMBOL_GPL(pata_parport_unregister_driver);
-
-static ssize_t new_device_store(struct bus_type *bus, const char *buf,
-                               size_t count)
-{
-       char port[12] = "auto";
-       char protocol[8] = "auto";
-       int mode = -1, unit = -1, delay = -1;
-       struct pi_protocol *pr, *pr_wanted;
-       struct device_driver *drv;
-       struct parport *parport;
-       int port_num, port_wanted, pr_num;
-       bool ok = false;
-
-       if (sscanf(buf, "%11s %7s %d %d %d",
-                       port, protocol, &mode, &unit, &delay) < 1)
-               return -EINVAL;
-
-       if (sscanf(port, "parport%u", &port_wanted) < 1) {
-               if (strcmp(port, "auto")) {
-                       pr_err("invalid port name %s\n", port);
-                       return -EINVAL;
-               }
-               port_wanted = -1;
-       }
-
-       drv = driver_find(protocol, &pata_parport_bus_type);
-       if (!drv) {
-               if (strcmp(protocol, "auto")) {
-                       pr_err("protocol %s not found\n", protocol);
-                       return -EINVAL;
-               }
-               pr_wanted = NULL;
-       } else {
-               pr_wanted = container_of(drv, struct pi_protocol, driver);
-       }
-
-       mutex_lock(&pi_mutex);
-       /* walk all parports */
-       idr_for_each_entry(&parport_list, parport, port_num) {
-               if (port_num == port_wanted || port_wanted == -1) {
-                       parport = parport_find_number(port_num);
-                       if (!parport) {
-                               pr_err("no such port %s\n", port);
-                               mutex_unlock(&pi_mutex);
-                               return -ENODEV;
-                       }
-                       /* walk all protocols */
-                       idr_for_each_entry(&protocols, pr, pr_num) {
-                               if (pr == pr_wanted || !pr_wanted)
-                                       if (pi_init_one(parport, pr, mode, unit,
-                                                       delay))
-                                               ok = true;
-                       }
-                       parport_put_port(parport);
-               }
-       }
-       mutex_unlock(&pi_mutex);
-       if (!ok)
-               return -ENODEV;
-
-       return count;
-}
-static BUS_ATTR_WO(new_device);
-
-static void pi_remove_one(struct device *dev)
-{
-       struct ata_host *host = dev_get_drvdata(dev);
-       struct pi_adapter *pi = host->private_data;
-
-       ata_host_detach(host);
-       pi_disconnect(pi);
-       pi_release(pi);
-       device_unregister(dev);
-       ida_free(&pata_parport_bus_dev_ids, dev->id);
-       /* pata_parport_dev_release will do kfree(pi) */
-}
-
-static ssize_t delete_device_store(struct bus_type *bus, const char *buf,
-                                  size_t count)
-{
-       struct device *dev;
-
-       mutex_lock(&pi_mutex);
-       dev = bus_find_device_by_name(bus, NULL, buf);
-       if (!dev) {
-               mutex_unlock(&pi_mutex);
-               return -ENODEV;
-       }
-
-       pi_remove_one(dev);
-       mutex_unlock(&pi_mutex);
-
-       return count;
-}
-static BUS_ATTR_WO(delete_device);
-
-static void pata_parport_attach(struct parport *port)
-{
-       struct pi_protocol *pr;
-       int pr_num, id;
-
-       mutex_lock(&pi_mutex);
-       id = idr_alloc(&parport_list, port, port->number, port->number,
-                      GFP_KERNEL);
-       if (id < 0) {
-               mutex_unlock(&pi_mutex);
-               return;
-       }
-
-       if (probe) {
-               /* probe this port using all protocols */
-               idr_for_each_entry(&protocols, pr, pr_num)
-                       pi_init_one(port, pr, -1, 0, -1);
-       }
-       mutex_unlock(&pi_mutex);
-}
-
-static int pi_remove_port(struct device *dev, void *p)
-{
-       struct ata_host *host = dev_get_drvdata(dev);
-       struct pi_adapter *pi = host->private_data;
-
-       if (pi->pardev->port == p)
-               pi_remove_one(dev);
-
-       return 0;
-}
-
-static void pata_parport_detach(struct parport *port)
-{
-       mutex_lock(&pi_mutex);
-       bus_for_each_dev(&pata_parport_bus_type, NULL, port, pi_remove_port);
-       idr_remove(&parport_list, port->number);
-       mutex_unlock(&pi_mutex);
-}
-
-static struct parport_driver pata_parport_driver = {
-       .name = DRV_NAME,
-       .match_port = pata_parport_attach,
-       .detach = pata_parport_detach,
-       .devmodel = true,
-};
-
-static __init int pata_parport_init(void)
-{
-       int error;
-
-       error = bus_register(&pata_parport_bus_type);
-       if (error) {
-               pr_err("failed to register pata_parport bus, error: %d\n", error);
-               return error;
-       }
-
-       error = device_register(&pata_parport_bus);
-       if (error) {
-               pr_err("failed to register pata_parport bus, error: %d\n", error);
-               goto out_unregister_bus;
-       }
-
-       error = bus_create_file(&pata_parport_bus_type, &bus_attr_new_device);
-       if (error) {
-               pr_err("unable to create sysfs file, error: %d\n", error);
-               goto out_unregister_dev;
-       }
-
-       error = bus_create_file(&pata_parport_bus_type, &bus_attr_delete_device);
-       if (error) {
-               pr_err("unable to create sysfs file, error: %d\n", error);
-               goto out_remove_new;
-       }
-
-       error = parport_register_driver(&pata_parport_driver);
-       if (error) {
-               pr_err("unable to register parport driver, error: %d\n", error);
-               goto out_remove_del;
-       }
-
-       return 0;
-
-out_remove_del:
-       bus_remove_file(&pata_parport_bus_type, &bus_attr_delete_device);
-out_remove_new:
-       bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
-out_unregister_dev:
-       device_unregister(&pata_parport_bus);
-out_unregister_bus:
-       bus_unregister(&pata_parport_bus_type);
-       return error;
-}
-
-static __exit void pata_parport_exit(void)
-{
-       parport_unregister_driver(&pata_parport_driver);
-       bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
-       bus_remove_file(&pata_parport_bus_type, &bus_attr_delete_device);
-       device_unregister(&pata_parport_bus);
-       bus_unregister(&pata_parport_bus_type);
-}
-
-MODULE_AUTHOR("Ondrej Zary");
-MODULE_DESCRIPTION("driver for parallel port ATA adapters");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("paride");
-
-module_init(pata_parport_init);
-module_exit(pata_parport_exit);
diff --git a/drivers/ata/pata_parport/Kconfig b/drivers/ata/pata_parport/Kconfig
new file mode 100644 (file)
index 0000000..0893a13
--- /dev/null
@@ -0,0 +1,141 @@
+# SPDX-License-Identifier: GPL-2.0
+
+comment "Parallel IDE protocol modules"
+       depends on PATA_PARPORT
+
+config PATA_PARPORT_ATEN
+       tristate "ATEN EH-100 protocol"
+       depends on PATA_PARPORT
+       help
+         This option enables support for the ATEN EH-100 parallel port IDE
+         protocol. This protocol is used in some inexpensive low performance
+         parallel port kits made in Hong Kong.
+
+config PATA_PARPORT_BPCK
+       tristate "MicroSolutions backpack (Series 5) protocol"
+       depends on PATA_PARPORT
+       help
+         This option enables support for the Micro Solutions BACKPACK
+         parallel port Series 5 IDE protocol.  (Most BACKPACK drives made
+         before 1999 were Series 5) Series 5 drives will NOT always have the
+         Series noted on the bottom of the drive. Series 6 drivers will.
+
+         In other words, if your BACKPACK drive doesn't say "Series 6" on the
+         bottom, enable this option.
+
+config PATA_PARPORT_BPCK6
+       tristate "MicroSolutions backpack (Series 6) protocol"
+       depends on (PATA_PARPORT) && !64BIT
+       help
+         This option enables support for the Micro Solutions BACKPACK
+         parallel port Series 6 IDE protocol.  (Most BACKPACK drives made
+         after 1999 were Series 6) Series 6 drives will have the Series noted
+         on the bottom of the drive.  Series 5 drivers don't always have it
+         noted.
+
+         In other words, if your BACKPACK drive says "Series 6" on the
+         bottom, enable this option.
+
+config PATA_PARPORT_COMM
+       tristate "DataStor Commuter protocol"
+       depends on PATA_PARPORT
+       help
+         This option enables support for the Commuter parallel port IDE
+         protocol from DataStor.
+
+config PATA_PARPORT_DSTR
+       tristate "DataStor EP-2000 protocol"
+       depends on PATA_PARPORT
+       help
+         This option enables support for the EP-2000 parallel port IDE
+         protocol from DataStor
+
+config PATA_PARPORT_FIT2
+       tristate "FIT TD-2000 protocol"
+       depends on PATA_PARPORT
+       help
+         This option enables support for the TD-2000 parallel port IDE
+         protocol from Fidelity International Technology. This is a simple
+         (low speed) adapter that is used in some portable hard drives.
+
+config PATA_PARPORT_FIT3
+       tristate "FIT TD-3000 protocol"
+       depends on PATA_PARPORT
+       help
+         This option enables support for the TD-3000 parallel port IDE
+         protocol from Fidelity International Technology. This protocol is
+         used in newer models of their portable disk, CD-ROM and PD/CD
+         devices.
+
+config PATA_PARPORT_EPAT
+       tristate "Shuttle EPAT/EPEZ protocol"
+       depends on PATA_PARPORT
+       help
+         This option enables support for the EPAT parallel port IDE protocol.
+         EPAT is a parallel port IDE adapter manufactured by Shuttle
+         Technology and widely used in devices from major vendors such as
+         Hewlett-Packard, SyQuest, Imation and Avatar.
+
+config PATA_PARPORT_EPATC8
+       bool "Support c7/c8 chips"
+       depends on PATA_PARPORT_EPAT
+       help
+         This option enables support for the newer Shuttle EP1284 (aka c7 and
+         c8) chip. You need this if you are using any recent Imation SuperDisk
+         (LS-120) drive.
+
+config PATA_PARPORT_EPIA
+       tristate "Shuttle EPIA protocol"
+       depends on PATA_PARPORT
+       help
+         This option enables support for the (obsolete) EPIA parallel port
+         IDE protocol from Shuttle Technology. This adapter can still be
+         found in some no-name kits.
+
+config PATA_PARPORT_FRIQ
+       tristate "Freecom IQ ASIC-2 protocol"
+       depends on PATA_PARPORT
+       help
+         This option enables support for version 2 of the Freecom IQ parallel
+         port IDE adapter.  This adapter is used by the Maxell Superdisk
+         drive.
+
+config PATA_PARPORT_FRPW
+       tristate "FreeCom power protocol"
+       depends on PATA_PARPORT
+       help
+         This option enables support for the Freecom power parallel port IDE
+         protocol.
+
+config PATA_PARPORT_KBIC
+       tristate "KingByte KBIC-951A/971A protocols"
+       depends on PATA_PARPORT
+       help
+         This option enables support for the KBIC-951A and KBIC-971A parallel
+         port IDE protocols from KingByte Information Corp. KingByte's
+         adapters appear in many no-name portable disk and CD-ROM products,
+         especially in Europe.
+
+config PATA_PARPORT_KTTI
+       tristate "KT PHd protocol"
+       depends on PATA_PARPORT
+       help
+         This option enables support for the "PHd" parallel port IDE protocol
+         from KT Technology. This is a simple (low speed) adapter that is
+         used in some 2.5" portable hard drives.
+
+config PATA_PARPORT_ON20
+       tristate "OnSpec 90c20 protocol"
+       depends on PATA_PARPORT
+       help
+         This option enables support for the (obsolete) 90c20 parallel port
+         IDE protocol from OnSpec (often marketed under the ValuStore brand
+         name).
+
+config PATA_PARPORT_ON26
+       tristate "OnSpec 90c26 protocol"
+       depends on PATA_PARPORT
+       help
+         This option enables support for the 90c26 parallel port IDE protocol
+         from OnSpec Electronics (often marketed under the ValuStore brand
+         name).
diff --git a/drivers/ata/pata_parport/Makefile b/drivers/ata/pata_parport/Makefile
new file mode 100644 (file)
index 0000000..0932c8d
--- /dev/null
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_PATA_PARPORT)      += pata_parport.o
+
+obj-$(CONFIG_PATA_PARPORT_ATEN)        += aten.o
+obj-$(CONFIG_PATA_PARPORT_BPCK)        += bpck.o
+obj-$(CONFIG_PATA_PARPORT_COMM)        += comm.o
+obj-$(CONFIG_PATA_PARPORT_DSTR)        += dstr.o
+obj-$(CONFIG_PATA_PARPORT_KBIC)        += kbic.o
+obj-$(CONFIG_PATA_PARPORT_EPAT)        += epat.o
+obj-$(CONFIG_PATA_PARPORT_EPIA)        += epia.o
+obj-$(CONFIG_PATA_PARPORT_FRPW)        += frpw.o
+obj-$(CONFIG_PATA_PARPORT_FRIQ)        += friq.o
+obj-$(CONFIG_PATA_PARPORT_FIT2)        += fit2.o
+obj-$(CONFIG_PATA_PARPORT_FIT3)        += fit3.o
+obj-$(CONFIG_PATA_PARPORT_ON20)        += on20.o
+obj-$(CONFIG_PATA_PARPORT_ON26)        += on26.o
+obj-$(CONFIG_PATA_PARPORT_KTTI)        += ktti.o
+obj-$(CONFIG_PATA_PARPORT_BPCK6) += bpck6.o
diff --git a/drivers/ata/pata_parport/aten.c b/drivers/ata/pata_parport/aten.c
new file mode 100644 (file)
index 0000000..b66508b
--- /dev/null
@@ -0,0 +1,162 @@
+/* 
+        aten.c  (c) 1997-8  Grant R. Guenther <grant@torque.net>
+                            Under the terms of the GNU General Public License.
+
+       aten.c is a low-level protocol driver for the ATEN EH-100
+       parallel port adapter.  The EH-100 supports 4-bit and 8-bit
+        modes only.  There is also an EH-132 which supports EPP mode
+        transfers.  The EH-132 is not yet supported.
+
+*/
+
+/* Changes:
+
+       1.01    GRG 1998.05.05  init_proto, release_proto
+
+*/
+
+#define ATEN_VERSION      "1.01"
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/wait.h>
+#include <linux/types.h>
+#include <asm/io.h>
+
+#include <linux/pata_parport.h>
+
+#define j44(a,b)                ((((a>>4)&0x0f)|(b&0xf0))^0x88)
+
+/* cont = 0 - access the IDE register file 
+   cont = 1 - access the IDE command set 
+*/
+
+static int  cont_map[2] = { 0x08, 0x20 };
+
+static void  aten_write_regr( PIA *pi, int cont, int regr, int val)
+
+{      int r;
+
+       r = regr + cont_map[cont] + 0x80;
+
+       w0(r); w2(0xe); w2(6); w0(val); w2(7); w2(6); w2(0xc);
+}
+
+static int aten_read_regr( PIA *pi, int cont, int regr )
+
+{      int  a, b, r;
+
+        r = regr + cont_map[cont] + 0x40;
+
+       switch (pi->mode) {
+
+        case 0: w0(r); w2(0xe); w2(6); 
+               w2(7); w2(6); w2(0);
+               a = r1(); w0(0x10); b = r1(); w2(0xc);
+               return j44(a,b);
+
+        case 1: r |= 0x10;
+               w0(r); w2(0xe); w2(6); w0(0xff); 
+               w2(0x27); w2(0x26); w2(0x20);
+               a = r0();
+               w2(0x26); w2(0xc);
+               return a;
+       }
+       return -1;
+}
+
+static void aten_read_block( PIA *pi, char * buf, int count )
+
+{      int  k, a, b, c, d;
+
+       switch (pi->mode) {
+
+       case 0: w0(0x48); w2(0xe); w2(6);
+               for (k=0;k<count/2;k++) {
+                       w2(7); w2(6); w2(2);
+                       a = r1(); w0(0x58); b = r1();
+                       w2(0); d = r1(); w0(0x48); c = r1();
+                       buf[2*k] = j44(c,d);
+                       buf[2*k+1] = j44(a,b);
+               }
+               w2(0xc);
+               break;
+
+       case 1: w0(0x58); w2(0xe); w2(6);
+               for (k=0;k<count/2;k++) {
+                       w2(0x27); w2(0x26); w2(0x22);
+                       a = r0(); w2(0x20); b = r0();
+                       buf[2*k] = b; buf[2*k+1] = a;
+               }
+               w2(0x26); w2(0xc);
+               break;
+       }
+}
+
+static void aten_write_block( PIA *pi, char * buf, int count )
+
+{      int k;
+
+       w0(0x88); w2(0xe); w2(6);
+       for (k=0;k<count/2;k++) {
+               w0(buf[2*k+1]); w2(0xe); w2(6);
+               w0(buf[2*k]); w2(7); w2(6);
+       }
+       w2(0xc);
+}
+
+static void aten_connect ( PIA *pi  )
+
+{       pi->saved_r0 = r0();
+        pi->saved_r2 = r2();
+       w2(0xc);        
+}
+
+static void aten_disconnect ( PIA *pi )
+
+{       w0(pi->saved_r0);
+        w2(pi->saved_r2);
+} 
+
+static void aten_log_adapter( PIA *pi, char * scratch, int verbose )
+
+{       char    *mode_string[2] = {"4-bit","8-bit"};
+
+        printk("%s: aten %s, ATEN EH-100 at 0x%x, ",
+                pi->device,ATEN_VERSION,pi->port);
+        printk("mode %d (%s), delay %d\n",pi->mode,
+               mode_string[pi->mode],pi->delay);
+
+}
+
+static struct pi_protocol aten = {
+       .owner          = THIS_MODULE,
+       .name           = "aten",
+       .max_mode       = 2,
+       .epp_first      = 2,
+       .default_delay  = 1,
+       .max_units      = 1,
+       .write_regr     = aten_write_regr,
+       .read_regr      = aten_read_regr,
+       .write_block    = aten_write_block,
+       .read_block     = aten_read_block,
+       .connect        = aten_connect,
+       .disconnect     = aten_disconnect,
+       .log_adapter    = aten_log_adapter,
+};
+
+static int __init aten_init(void)
+{
+       return paride_register(&aten);
+}
+
+static void __exit aten_exit(void)
+{
+       paride_unregister( &aten );
+}
+
+MODULE_LICENSE("GPL");
+module_init(aten_init)
+module_exit(aten_exit)
diff --git a/drivers/ata/pata_parport/bpck.c b/drivers/ata/pata_parport/bpck.c
new file mode 100644 (file)
index 0000000..5fb3cf9
--- /dev/null
@@ -0,0 +1,477 @@
+/* 
+       bpck.c  (c) 1996-8  Grant R. Guenther <grant@torque.net>
+                           Under the terms of the GNU General Public License.
+
+       bpck.c is a low-level protocol driver for the MicroSolutions 
+       "backpack" parallel port IDE adapter.  
+
+*/
+
+/* Changes:
+
+       1.01    GRG 1998.05.05 init_proto, release_proto, pi->delay 
+       1.02    GRG 1998.08.15 default pi->delay returned to 4
+
+*/
+
+#define        BPCK_VERSION    "1.02" 
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <asm/io.h>
+
+#include <linux/pata_parport.h>
+
+#undef r2
+#undef w2
+#undef PC
+
+#define PC                     pi->private
+#define r2()                   (PC=(in_p(2) & 0xff))
+#define w2(byte)               {out_p(2,byte); PC = byte;}
+#define t2(pat)                {PC ^= pat; out_p(2,PC);}
+#define e2()                   {PC &= 0xfe; out_p(2,PC);}
+#define o2()                   {PC |= 1; out_p(2,PC);}
+
+#define j44(l,h)     (((l>>3)&0x7)|((l>>4)&0x8)|((h<<1)&0x70)|(h&0x80))
+
+/* cont = 0 - access the IDE register file 
+   cont = 1 - access the IDE command set 
+   cont = 2 - use internal bpck register addressing
+*/
+
+static int  cont_map[3] = { 0x40, 0x48, 0 };
+
+static int bpck_read_regr( PIA *pi, int cont, int regr )
+
+{       int r, l, h;
+
+       r = regr + cont_map[cont];
+
+       switch (pi->mode) {
+
+       case 0: w0(r & 0xf); w0(r); t2(2); t2(4);
+               l = r1();
+               t2(4);
+               h = r1();
+               return j44(l,h);
+
+       case 1: w0(r & 0xf); w0(r); t2(2);
+               e2(); t2(0x20);
+               t2(4); h = r0();
+               t2(1); t2(0x20);
+               return h;
+
+       case 2:
+       case 3:
+       case 4: w0(r); w2(9); w2(0); w2(0x20);
+               h = r4();
+               w2(0);
+               return h;
+
+       }
+       return -1;
+}      
+
+static void bpck_write_regr( PIA *pi, int cont, int regr, int val )
+
+{      int     r;
+
+        r = regr + cont_map[cont];
+
+       switch (pi->mode) {
+
+       case 0:
+       case 1: w0(r);
+               t2(2);
+               w0(val);
+               o2(); t2(4); t2(1);
+               break;
+
+       case 2:
+       case 3:
+       case 4: w0(r); w2(9); w2(0);
+               w0(val); w2(1); w2(3); w2(0);
+               break;
+
+       }
+}
+
+/* These macros access the bpck registers in native addressing */
+
+#define WR(r,v)                bpck_write_regr(pi,2,r,v)
+#define RR(r)          (bpck_read_regr(pi,2,r))
+
+static void bpck_write_block( PIA *pi, char * buf, int count )
+
+{      int i;
+
+       switch (pi->mode) {
+
+       case 0: WR(4,0x40);
+               w0(0x40); t2(2); t2(1);
+               for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
+               WR(4,0);
+               break;
+
+       case 1: WR(4,0x50);
+                w0(0x40); t2(2); t2(1);
+                for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
+                WR(4,0x10);
+               break;
+
+       case 2: WR(4,0x48);
+               w0(0x40); w2(9); w2(0); w2(1);
+               for (i=0;i<count;i++) w4(buf[i]);
+               w2(0);
+               WR(4,8);
+               break;
+
+        case 3: WR(4,0x48);
+                w0(0x40); w2(9); w2(0); w2(1);
+                for (i=0;i<count/2;i++) w4w(((u16 *)buf)[i]);
+                w2(0);
+                WR(4,8);
+                break;
+        case 4: WR(4,0x48);
+                w0(0x40); w2(9); w2(0); w2(1);
+                for (i=0;i<count/4;i++) w4l(((u32 *)buf)[i]);
+                w2(0);
+                WR(4,8);
+                break;
+       }
+}
+
+static void bpck_read_block( PIA *pi, char * buf, int count )
+
+{      int i, l, h;
+
+       switch (pi->mode) {
+
+       case 0: WR(4,0x40);
+               w0(0x40); t2(2);
+               for (i=0;i<count;i++) {
+                   t2(4); l = r1();
+                   t2(4); h = r1();
+                   buf[i] = j44(l,h);
+               }
+               WR(4,0);
+               break;
+
+       case 1: WR(4,0x50);
+               w0(0x40); t2(2); t2(0x20);
+               for(i=0;i<count;i++) { t2(4); buf[i] = r0(); }
+               t2(1); t2(0x20);
+               WR(4,0x10);
+               break;
+
+       case 2: WR(4,0x48);
+               w0(0x40); w2(9); w2(0); w2(0x20);
+               for (i=0;i<count;i++) buf[i] = r4();
+               w2(0);
+               WR(4,8);
+               break;
+
+        case 3: WR(4,0x48);
+                w0(0x40); w2(9); w2(0); w2(0x20);
+                for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
+                w2(0);
+                WR(4,8);
+                break;
+
+        case 4: WR(4,0x48);
+                w0(0x40); w2(9); w2(0); w2(0x20);
+                for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
+                w2(0);
+                WR(4,8);
+                break;
+
+       }
+}
+
+static int bpck_probe_unit ( PIA *pi )
+
+{      int o1, o0, f7, id;
+       int t, s;
+
+       id = pi->unit;
+       s = 0;
+       w2(4); w2(0xe); r2(); t2(2); 
+       o1 = r1()&0xf8;
+       o0 = r0();
+       w0(255-id); w2(4); w0(id);
+       t2(8); t2(8); t2(8);
+       t2(2); t = r1()&0xf8;
+       f7 = ((id % 8) == 7);
+       if ((f7) || (t != o1)) { t2(2); s = r1()&0xf8; }
+       if ((t == o1) && ((!f7) || (s == o1)))  {
+               w2(0x4c); w0(o0);
+               return 0;       
+       }
+       t2(8); w0(0); t2(2); w2(0x4c); w0(o0);
+       return 1;
+}
+       
+static void bpck_connect ( PIA *pi  )
+
+{       pi->saved_r0 = r0();
+       w0(0xff-pi->unit); w2(4); w0(pi->unit);
+       t2(8); t2(8); t2(8); 
+       t2(2); t2(2);
+       
+       switch (pi->mode) {
+
+       case 0: t2(8); WR(4,0);
+               break;
+
+       case 1: t2(8); WR(4,0x10);
+               break;
+
+       case 2:
+        case 3:
+       case 4: w2(0); WR(4,8);
+               break;
+
+       }
+
+       WR(5,8);
+
+       if (pi->devtype == PI_PCD) {
+               WR(0x46,0x10);          /* fiddle with ESS logic ??? */
+               WR(0x4c,0x38);
+               WR(0x4d,0x88);
+               WR(0x46,0xa0);
+               WR(0x41,0);
+               WR(0x4e,8);
+               }
+}
+
+static void bpck_disconnect ( PIA *pi )
+
+{      w0(0); 
+       if (pi->mode >= 2) { w2(9); w2(0); } else t2(2);
+       w2(0x4c); w0(pi->saved_r0);
+} 
+
+static void bpck_force_spp ( PIA *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);
+
+        w2(0); 
+        w0(4); w2(9); w2(0); 
+        w0(0); w2(1); w2(3); w2(0);     
+        w0(0); w2(9); w2(0);
+        w2(0x4c); w0(pi->saved_r0);
+}
+
+#define TEST_LEN  16
+
+static int bpck_test_proto( PIA *pi, char * scratch, int verbose )
+
+{      int i, e, l, h, om;
+       char buf[TEST_LEN];
+
+       bpck_force_spp(pi);
+
+       switch (pi->mode) {
+
+       case 0: bpck_connect(pi);
+               WR(0x13,0x7f);
+               w0(0x13); t2(2);
+               for(i=0;i<TEST_LEN;i++) {
+                    t2(4); l = r1();
+                    t2(4); h = r1();
+                    buf[i] = j44(l,h);
+               }
+               bpck_disconnect(pi);
+               break;
+
+        case 1: bpck_connect(pi);
+               WR(0x13,0x7f);
+                w0(0x13); t2(2); t2(0x20);
+                for(i=0;i<TEST_LEN;i++) { t2(4); buf[i] = r0(); }
+                t2(1); t2(0x20);
+               bpck_disconnect(pi);
+               break;
+
+       case 2:
+       case 3:
+       case 4: om = pi->mode;
+               pi->mode = 0;
+               bpck_connect(pi);
+               WR(7,3);
+               WR(4,8);
+               bpck_disconnect(pi);
+
+               pi->mode = om;
+               bpck_connect(pi);
+               w0(0x13); w2(9); w2(1); w0(0); w2(3); w2(0); w2(0xe0);
+
+               switch (pi->mode) {
+                 case 2: for (i=0;i<TEST_LEN;i++) buf[i] = r4();
+                         break;
+                 case 3: for (i=0;i<TEST_LEN/2;i++) ((u16 *)buf)[i] = r4w();
+                          break;
+                 case 4: for (i=0;i<TEST_LEN/4;i++) ((u32 *)buf)[i] = r4l();
+                          break;
+               }
+
+               w2(0);
+               WR(7,0);
+               bpck_disconnect(pi);
+
+               break;
+
+       }
+
+       if (verbose) {
+           printk("%s: bpck: 0x%x unit %d mode %d: ",
+                  pi->device,pi->port,pi->unit,pi->mode);
+           for (i=0;i<TEST_LEN;i++) printk("%3d",buf[i]);
+           printk("\n");
+       }
+
+       e = 0;
+       for (i=0;i<TEST_LEN;i++) if (buf[i] != (i+1)) e++;
+       return e;
+}
+
+static void bpck_read_eeprom ( PIA *pi, char * buf )
+
+{       int i, j, k, p, v, f, om, od;
+
+       bpck_force_spp(pi);
+
+       om = pi->mode;  od = pi->delay;
+       pi->mode = 0; pi->delay = 6;
+
+       bpck_connect(pi);
+       
+       WR(4,0);
+       for (i=0;i<64;i++) {
+           WR(6,8);  
+           WR(6,0xc);
+           p = 0x100;
+           for (k=0;k<9;k++) {
+               f = (((i + 0x180) & p) != 0) * 2;
+               WR(6,f+0xc); 
+               WR(6,f+0xd); 
+               WR(6,f+0xc);
+               p = (p >> 1);
+           }
+           for (j=0;j<2;j++) {
+               v = 0;
+               for (k=0;k<8;k++) {
+                   WR(6,0xc); 
+                   WR(6,0xd); 
+                   WR(6,0xc); 
+                   f = RR(0);
+                   v = 2*v + (f == 0x84);
+               }
+               buf[2*i+1-j] = v;
+           }
+       }
+       WR(6,8);
+       WR(6,0);
+       WR(5,8);
+
+       bpck_disconnect(pi);
+
+        if (om >= 2) {
+                bpck_connect(pi);
+                WR(7,3);
+                WR(4,8);
+                bpck_disconnect(pi);
+        }
+
+       pi->mode = om; pi->delay = od;
+}
+
+static int bpck_test_port ( PIA *pi )  /* check for 8-bit port */
+
+{      int     i, r, m;
+
+       w2(0x2c); i = r0(); w0(255-i); r = r0(); w0(i);
+       m = -1;
+       if (r == i) m = 2;
+       if (r == (255-i)) m = 0;
+
+       w2(0xc); i = r0(); w0(255-i); r = r0(); w0(i);
+       if (r != (255-i)) m = -1;
+       
+       if (m == 0) { w2(6); w2(0xc); r = r0(); w0(0xaa); w0(r); w0(0xaa); }
+       if (m == 2) { w2(0x26); w2(0xc); }
+
+       if (m == -1) return 0;
+       return 5;
+}
+
+static void bpck_log_adapter( PIA *pi, char * scratch, int verbose )
+
+{      char    *mode_string[5] = { "4-bit","8-bit","EPP-8",
+                                   "EPP-16","EPP-32" };
+
+#ifdef DUMP_EEPROM
+       int i;
+#endif
+
+       bpck_read_eeprom(pi,scratch);
+
+#ifdef DUMP_EEPROM
+       if (verbose) {
+          for(i=0;i<128;i++)
+               if ((scratch[i] < ' ') || (scratch[i] > '~'))
+                   scratch[i] = '.';
+          printk("%s: bpck EEPROM: %64.64s\n",pi->device,scratch);
+          printk("%s:              %64.64s\n",pi->device,&scratch[64]);
+       }
+#endif
+
+       printk("%s: bpck %s, backpack %8.8s unit %d",
+               pi->device,BPCK_VERSION,&scratch[110],pi->unit);
+       printk(" at 0x%x, mode %d (%s), delay %d\n",pi->port,
+               pi->mode,mode_string[pi->mode],pi->delay);
+}
+
+static struct pi_protocol bpck = {
+       .owner          = THIS_MODULE,
+       .name           = "bpck",
+       .max_mode       = 5,
+       .epp_first      = 2,
+       .default_delay  = 4,
+       .max_units      = 255,
+       .write_regr     = bpck_write_regr,
+       .read_regr      = bpck_read_regr,
+       .write_block    = bpck_write_block,
+       .read_block     = bpck_read_block,
+       .connect        = bpck_connect,
+       .disconnect     = bpck_disconnect,
+       .test_port      = bpck_test_port,
+       .probe_unit     = bpck_probe_unit,
+       .test_proto     = bpck_test_proto,
+       .log_adapter    = bpck_log_adapter,
+};
+
+static int __init bpck_init(void)
+{
+       return paride_register(&bpck);
+}
+
+static void __exit bpck_exit(void)
+{
+       paride_unregister(&bpck);
+}
+
+MODULE_LICENSE("GPL");
+module_init(bpck_init)
+module_exit(bpck_exit)
diff --git a/drivers/ata/pata_parport/bpck6.c b/drivers/ata/pata_parport/bpck6.c
new file mode 100644 (file)
index 0000000..d897e2a
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+       backpack.c (c) 2001 Micro Solutions Inc.
+               Released under the terms of the GNU General Public license
+
+       backpack.c is a low-level protocol driver for the Micro Solutions
+               "BACKPACK" parallel port IDE adapter
+               (Works on Series 6 drives)
+
+       Written by: Ken Hahn     (linux-dev@micro-solutions.com)
+                   Clive Turvey (linux-dev@micro-solutions.com)
+
+*/
+
+/*
+   This is Ken's linux wrapper for the PPC library
+   Version 1.0.0 is the backpack driver for which source is not available
+   Version 2.0.0 is the first to have source released 
+   Version 2.0.1 is the "Cox-ified" source code 
+   Version 2.0.2 - fixed version string usage, and made ppc functions static 
+*/
+
+
+#define BACKPACK_VERSION "2.0.2"
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <linux/parport.h>
+
+#include "ppc6lnx.c"
+#include <linux/pata_parport.h>
+
+/* PARAMETERS */
+static bool verbose; /* set this to 1 to see debugging messages and whatnot */
+
+#define PPCSTRUCT(pi) ((Interface *)(pi->private))
+
+/****************************************************************/
+/*
+ ATAPI CDROM DRIVE REGISTERS
+*/
+#define ATAPI_DATA       0      /* data port                  */
+#define ATAPI_ERROR      1      /* error register (read)      */
+#define ATAPI_FEATURES   1      /* feature register (write)   */
+#define ATAPI_INT_REASON 2      /* interrupt reason register  */
+#define ATAPI_COUNT_LOW  4      /* byte count register (low)  */
+#define ATAPI_COUNT_HIGH 5      /* byte count register (high) */
+#define ATAPI_DRIVE_SEL  6      /* drive select register      */
+#define ATAPI_STATUS     7      /* status port (read)         */
+#define ATAPI_COMMAND    7      /* command port (write)       */
+#define ATAPI_ALT_STATUS 0x0e /* alternate status reg (read) */
+#define ATAPI_DEVICE_CONTROL 0x0e /* device control (write)   */
+/****************************************************************/
+
+static int bpck6_read_regr(PIA *pi, int cont, int reg)
+{
+       unsigned int out;
+
+       /* check for bad settings */
+       if (reg<0 || reg>7 || cont<0 || cont>2)
+       {
+               return(-1);
+       }
+       out=ppc6_rd_port(PPCSTRUCT(pi),cont?reg|8:reg);
+       return(out);
+}
+
+static void bpck6_write_regr(PIA *pi, int cont, int reg, int val)
+{
+       /* check for bad settings */
+       if (reg>=0 && reg<=7 && cont>=0 && cont<=1)
+       {
+               ppc6_wr_port(PPCSTRUCT(pi),cont?reg|8:reg,(u8)val);
+       }
+}
+
+static void bpck6_write_block( PIA *pi, char * buf, int len )
+{
+       ppc6_wr_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(u32)len>>1); 
+}
+
+static void bpck6_read_block( PIA *pi, char * buf, int len )
+{
+       ppc6_rd_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(u32)len>>1);
+}
+
+static void bpck6_connect ( PIA *pi  )
+{
+       if(verbose)
+       {
+               printk(KERN_DEBUG "connect\n");
+       }
+
+       if(pi->mode >=2)
+       {
+               PPCSTRUCT(pi)->mode=4+pi->mode-2;       
+       }
+       else if(pi->mode==1)
+       {
+               PPCSTRUCT(pi)->mode=3;  
+       }
+       else
+       {
+               PPCSTRUCT(pi)->mode=1;          
+       }
+
+       ppc6_open(PPCSTRUCT(pi));  
+       ppc6_wr_extout(PPCSTRUCT(pi),0x3);
+}
+
+static void bpck6_disconnect ( PIA *pi )
+{
+       if(verbose)
+       {
+               printk("disconnect\n");
+       }
+       ppc6_wr_extout(PPCSTRUCT(pi),0x0);
+       ppc6_close(PPCSTRUCT(pi));
+}
+
+static int bpck6_test_port ( PIA *pi )   /* check for 8-bit port */
+{
+       if(verbose)
+       {
+               printk(KERN_DEBUG "PARPORT indicates modes=%x for lp=0x%lx\n",
+                               ((struct pardevice*)(pi->pardev))->port->modes,
+                       ((struct pardevice *)(pi->pardev))->port->base); 
+       }
+
+       /*copy over duplicate stuff.. initialize state info*/
+       PPCSTRUCT(pi)->ppc_id=pi->unit;
+       PPCSTRUCT(pi)->lpt_addr=pi->port;
+
+       /* look at the parport device to see if what modes we can use */
+       if(((struct pardevice *)(pi->pardev))->port->modes & 
+               (PARPORT_MODE_EPP)
+          )
+       {
+               return 5; /* Can do EPP*/
+       }
+       else if(((struct pardevice *)(pi->pardev))->port->modes & 
+                       (PARPORT_MODE_TRISTATE)
+               )
+       {
+               return 2;
+       }
+       else /*Just flat SPP*/
+       {
+               return 1;
+       }
+}
+
+static int bpck6_probe_unit ( PIA *pi )
+{
+       int out;
+
+       if(verbose)
+       {
+               printk(KERN_DEBUG "PROBE UNIT %x on port:%x\n",pi->unit,pi->port);
+       }
+
+       /*SET PPC UNIT NUMBER*/
+       PPCSTRUCT(pi)->ppc_id=pi->unit;
+
+       /*LOWER DOWN TO UNIDIRECTIONAL*/
+       PPCSTRUCT(pi)->mode=1;          
+
+       out=ppc6_open(PPCSTRUCT(pi));
+
+       if(verbose)
+       {
+               printk(KERN_DEBUG "ppc_open returned %2x\n",out);
+       }
+
+       if(out)
+       {
+               ppc6_close(PPCSTRUCT(pi));
+               if(verbose)
+               {
+                       printk(KERN_DEBUG "leaving probe\n");
+               }
+               return(1);
+       }
+       else
+       {
+               if(verbose)
+               {
+                       printk(KERN_DEBUG "Failed open\n");
+               }
+               return(0);
+       }
+}
+
+static void bpck6_log_adapter( PIA *pi, char * scratch, int verbose )
+{
+       char *mode_string[5]=
+               {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
+
+       printk("%s: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n",pi->device);
+       printk("%s: Copyright 2001 by Micro Solutions, Inc., DeKalb IL.\n",pi->device);
+       printk("%s: BACKPACK %s, Micro Solutions BACKPACK Drive at 0x%x\n",
+               pi->device,BACKPACK_VERSION,pi->port);
+       printk("%s: Unit: %d Mode:%d (%s) Delay %d\n",pi->device,
+               pi->unit,pi->mode,mode_string[pi->mode],pi->delay);
+}
+
+static int bpck6_init_proto(PIA *pi)
+{
+       Interface *p = kzalloc(sizeof(Interface), GFP_KERNEL);
+
+       if (p) {
+               pi->private = (unsigned long)p;
+               return 0;
+       }
+
+       printk(KERN_ERR "%s: ERROR COULDN'T ALLOCATE MEMORY\n", pi->device); 
+       return -1;
+}
+
+static void bpck6_release_proto(PIA *pi)
+{
+       kfree((void *)(pi->private)); 
+}
+
+static struct pi_protocol bpck6 = {
+       .owner          = THIS_MODULE,
+       .name           = "bpck6",
+       .max_mode       = 5,
+       .epp_first      = 2, /* 2-5 use epp (need 8 ports) */
+       .max_units      = 255,
+       .write_regr     = bpck6_write_regr,
+       .read_regr      = bpck6_read_regr,
+       .write_block    = bpck6_write_block,
+       .read_block     = bpck6_read_block,
+       .connect        = bpck6_connect,
+       .disconnect     = bpck6_disconnect,
+       .test_port      = bpck6_test_port,
+       .probe_unit     = bpck6_probe_unit,
+       .log_adapter    = bpck6_log_adapter,
+       .init_proto     = bpck6_init_proto,
+       .release_proto  = bpck6_release_proto,
+};
+
+static int __init bpck6_init(void)
+{
+       printk(KERN_INFO "bpck6: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n");
+       printk(KERN_INFO "bpck6: Copyright 2001 by Micro Solutions, Inc., DeKalb IL. USA\n");
+       if(verbose)
+               printk(KERN_DEBUG "bpck6: verbose debug enabled.\n");
+       return paride_register(&bpck6);
+}
+
+static void __exit bpck6_exit(void)
+{
+       paride_unregister(&bpck6);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Micro Solutions Inc.");
+MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE");
+module_param(verbose, bool, 0644);
+module_init(bpck6_init)
+module_exit(bpck6_exit)
diff --git a/drivers/ata/pata_parport/comm.c b/drivers/ata/pata_parport/comm.c
new file mode 100644 (file)
index 0000000..1775e7e
--- /dev/null
@@ -0,0 +1,218 @@
+/* 
+        comm.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
+                              Under the terms of the GNU General Public License.
+
+       comm.c is a low-level protocol driver for some older models
+       of the DataStor "Commuter" parallel to IDE adapter.  Some of
+       the parallel port devices marketed by Arista currently
+       use this adapter.
+*/
+
+/* Changes:
+
+       1.01    GRG 1998.05.05  init_proto, release_proto
+
+*/
+
+#define COMM_VERSION      "1.01"
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <asm/io.h>
+
+#include <linux/pata_parport.h>
+
+/* mode codes:  0  nybble reads, 8-bit writes
+                1  8-bit reads and writes
+                2  8-bit EPP mode
+*/
+
+#define j44(a,b)       (((a>>3)&0x0f)|((b<<1)&0xf0))
+
+#define P1     w2(5);w2(0xd);w2(0xd);w2(5);w2(4);
+#define P2     w2(5);w2(7);w2(7);w2(5);w2(4);
+
+/* cont = 0 - access the IDE register file 
+   cont = 1 - access the IDE command set 
+*/
+
+static int  cont_map[2] = { 0x08, 0x10 };
+
+static int comm_read_regr( PIA *pi, int cont, int regr )
+
+{       int     l, h, r;
+
+        r = regr + cont_map[cont];
+
+        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 1: w0(r+0x20); P1; 
+               w0(0); w2(0x26); h = r0(); w2(4);
+                return h;
+
+       case 2:
+       case 3:
+        case 4: w3(r+0x20); (void)r1();
+               w2(0x24); h = r4(); w2(4);
+                return h;
+
+        }
+        return -1;
+}       
+
+static void comm_write_regr( PIA *pi, int cont, int regr, int val )
+
+{       int  r;
+
+        r = regr + cont_map[cont];
+
+        switch (pi->mode)  {
+
+        case 0:
+        case 1: w0(r); P1; w0(val); P2;
+               break;
+
+       case 2:
+       case 3:
+        case 4: w3(r); (void)r1(); w4(val);
+                break;
+        }
+}
+
+static void comm_connect ( PIA *pi  )
+
+{       pi->saved_r0 = r0();
+        pi->saved_r2 = r2();
+        w2(4); w0(0xff); w2(6);
+        w2(4); w0(0xaa); w2(6);
+        w2(4); w0(0x00); w2(6);
+        w2(4); w0(0x87); w2(6);
+        w2(4); w0(0xe0); w2(0xc); w2(0xc); w2(4);
+}
+
+static void comm_disconnect ( PIA *pi )
+
+{       w2(0); w2(0); w2(0); w2(4); 
+       w0(pi->saved_r0);
+        w2(pi->saved_r2);
+} 
+
+static void comm_read_block( PIA *pi, char * buf, int count )
+
+{       int     i, l, h;
+
+        switch (pi->mode) {
+        
+        case 0: w0(0x48); P1;
+                for(i=0;i<count;i++) {
+                        w0(0); w2(6); l = r1();
+                        w0(0x80); h = r1(); w2(4);
+                        buf[i] = j44(l,h);
+                }
+                break;
+
+        case 1: w0(0x68); P1; w0(0);
+                for(i=0;i<count;i++) {
+                        w2(0x26); buf[i] = r0(); w2(0x24);
+                }
+               w2(4);
+               break;
+               
+       case 2: w3(0x68); (void)r1(); w2(0x24);
+               for (i=0;i<count;i++) buf[i] = r4();
+               w2(4);
+               break;
+
+        case 3: w3(0x68); (void)r1(); w2(0x24);
+                for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
+                w2(4);
+                break;
+
+        case 4: w3(0x68); (void)r1(); w2(0x24);
+                for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
+                w2(4);
+                break;
+               
+       }
+}
+
+/* NB: Watch out for the byte swapped writes ! */
+
+static void comm_write_block( PIA *pi, char * buf, int count )
+
+{       int    k;
+
+        switch (pi->mode) {
+
+        case 0:
+        case 1: w0(0x68); P1;
+               for (k=0;k<count;k++) {
+                        w2(5); w0(buf[k^1]); w2(7);
+                }
+                w2(5); w2(4);
+                break;
+
+        case 2: w3(0x48); (void)r1();
+                for (k=0;k<count;k++) w4(buf[k^1]);
+                break;
+
+        case 3: w3(0x48); (void)r1();
+                for (k=0;k<count/2;k++) w4w(pi_swab16(buf,k));
+                break;
+
+        case 4: w3(0x48); (void)r1();
+                for (k=0;k<count/4;k++) w4l(pi_swab32(buf,k));
+                break;
+
+
+        }
+}
+
+static void comm_log_adapter( PIA *pi, char * scratch, int verbose )
+
+{       char    *mode_string[5] = {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
+
+        printk("%s: comm %s, DataStor Commuter at 0x%x, ",
+                pi->device,COMM_VERSION,pi->port);
+        printk("mode %d (%s), delay %d\n",pi->mode,
+               mode_string[pi->mode],pi->delay);
+
+}
+
+static struct pi_protocol comm = {
+       .owner          = THIS_MODULE,
+       .name           = "comm",
+       .max_mode       = 5,
+       .epp_first      = 2,
+       .default_delay  = 1,
+       .max_units      = 1,
+       .write_regr     = comm_write_regr,
+       .read_regr      = comm_read_regr,
+       .write_block    = comm_write_block,
+       .read_block     = comm_read_block,
+       .connect        = comm_connect,
+       .disconnect     = comm_disconnect,
+       .log_adapter    = comm_log_adapter,
+};
+
+static int __init comm_init(void)
+{
+       return paride_register(&comm);
+}
+
+static void __exit comm_exit(void)
+{
+       paride_unregister(&comm);
+}
+
+MODULE_LICENSE("GPL");
+module_init(comm_init)
+module_exit(comm_exit)
diff --git a/drivers/ata/pata_parport/dstr.c b/drivers/ata/pata_parport/dstr.c
new file mode 100644 (file)
index 0000000..edf414d
--- /dev/null
@@ -0,0 +1,233 @@
+/* 
+        dstr.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
+                              Under the terms of the GNU General Public License.
+
+        dstr.c is a low-level protocol driver for the 
+        DataStor EP2000 parallel to IDE adapter chip.
+
+*/
+
+/* Changes:
+
+        1.01    GRG 1998.05.06 init_proto, release_proto
+
+*/
+
+#define DSTR_VERSION      "1.01"
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <asm/io.h>
+
+#include <linux/pata_parport.h>
+
+/* mode codes:  0  nybble reads, 8-bit writes
+                1  8-bit reads and writes
+                2  8-bit EPP mode
+               3  EPP-16
+               4  EPP-32
+*/
+
+#define j44(a,b)  (((a>>3)&0x07)|((~a>>4)&0x08)|((b<<1)&0x70)|((~b)&0x80))
+
+#define P1     w2(5);w2(0xd);w2(5);w2(4);
+#define P2     w2(5);w2(7);w2(5);w2(4);
+#define P3      w2(6);w2(4);w2(6);w2(4);
+
+/* cont = 0 - access the IDE register file 
+   cont = 1 - access the IDE command set 
+*/
+
+static int  cont_map[2] = { 0x20, 0x40 };
+
+static int dstr_read_regr( PIA *pi, int cont, int regr )
+
+{       int     a, b, r;
+
+        r = regr + cont_map[cont];
+
+       w0(0x81); P1;
+       if (pi->mode) { w0(0x11); } else { w0(1); }
+       P2; w0(r); P1;
+
+        switch (pi->mode)  {
+
+        case 0: w2(6); a = r1(); w2(4); w2(6); b = r1(); w2(4);
+                return j44(a,b);
+
+        case 1: w0(0); w2(0x26); a = r0(); w2(4);
+                return a;
+
+       case 2:
+       case 3:
+        case 4: w2(0x24); a = r4(); w2(4);
+                return a;
+
+        }
+        return -1;
+}       
+
+static void dstr_write_regr(  PIA *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);\
+                w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);w0(0x78);\
+                w0(x);w2(5);w2(4);
+
+static void dstr_connect ( PIA *pi  )
+
+{       pi->saved_r0 = r0();
+        pi->saved_r2 = r2();
+        w2(4); CCP(0xe0); w0(0xff);
+}
+
+static void dstr_disconnect ( PIA *pi )
+
+{       CCP(0x30);
+        w0(pi->saved_r0);
+        w2(pi->saved_r2);
+} 
+
+static void dstr_read_block( PIA *pi, char * buf, int count )
+
+{       int     k, a, b;
+
+        w0(0x81); P1;
+        if (pi->mode) { w0(0x19); } else { w0(9); }
+       P2; w0(0x82); P1; P3; w0(0x20); P1;
+
+        switch (pi->mode) {
+
+        case 0: for (k=0;k<count;k++) {
+                        w2(6); a = r1(); w2(4);
+                        w2(6); b = r1(); w2(4);
+                        buf[k] = j44(a,b);
+                } 
+                break;
+
+        case 1: w0(0);
+                for (k=0;k<count;k++) {
+                        w2(0x26); buf[k] = r0(); w2(0x24);
+                }
+                w2(4);
+                break;
+
+        case 2: w2(0x24); 
+                for (k=0;k<count;k++) buf[k] = r4();
+                w2(4);
+                break;
+
+        case 3: w2(0x24); 
+                for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
+                w2(4);
+                break;
+
+        case 4: w2(0x24); 
+                for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
+                w2(4);
+                break;
+
+        }
+}
+
+static void dstr_write_block( PIA *pi, char * buf, int count )
+
+{       int    k;
+
+        w0(0x81); P1;
+        if (pi->mode) { w0(0x19); } else { w0(9); }
+        P2; w0(0x82); P1; P3; w0(0x20); P1;
+
+        switch (pi->mode) {
+
+        case 0:
+        case 1: for (k=0;k<count;k++) {
+                        w2(5); w0(buf[k]); w2(7);
+                }
+                w2(5); w2(4);
+                break;
+
+        case 2: w2(0xc5);
+                for (k=0;k<count;k++) w4(buf[k]);
+               w2(0xc4);
+                break;
+
+        case 3: w2(0xc5);
+                for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
+                w2(0xc4);
+                break;
+
+        case 4: w2(0xc5);
+                for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
+                w2(0xc4);
+                break;
+
+        }
+}
+
+
+static void dstr_log_adapter( PIA *pi, char * scratch, int verbose )
+
+{       char    *mode_string[5] = {"4-bit","8-bit","EPP-8",
+                                  "EPP-16","EPP-32"};
+
+        printk("%s: dstr %s, DataStor EP2000 at 0x%x, ",
+                pi->device,DSTR_VERSION,pi->port);
+        printk("mode %d (%s), delay %d\n",pi->mode,
+               mode_string[pi->mode],pi->delay);
+
+}
+
+static struct pi_protocol dstr = {
+       .owner          = THIS_MODULE,
+       .name           = "dstr",
+       .max_mode       = 5,
+       .epp_first      = 2,
+       .default_delay  = 1,
+       .max_units      = 1,
+       .write_regr     = dstr_write_regr,
+       .read_regr      = dstr_read_regr,
+       .write_block    = dstr_write_block,
+       .read_block     = dstr_read_block,
+       .connect        = dstr_connect,
+       .disconnect     = dstr_disconnect,
+       .log_adapter    = dstr_log_adapter,
+};
+
+static int __init dstr_init(void)
+{
+       return paride_register(&dstr);
+}
+
+static void __exit dstr_exit(void)
+{
+       paride_unregister(&dstr);
+}
+
+MODULE_LICENSE("GPL");
+module_init(dstr_init)
+module_exit(dstr_exit)
diff --git a/drivers/ata/pata_parport/epat.c b/drivers/ata/pata_parport/epat.c
new file mode 100644 (file)
index 0000000..6ce2dee
--- /dev/null
@@ -0,0 +1,340 @@
+/* 
+        epat.c  (c) 1997-8  Grant R. Guenther <grant@torque.net>
+                            Under the terms of the GNU General Public License.
+
+       This is the low level protocol driver for the EPAT parallel
+        to IDE adapter from Shuttle Technologies.  This adapter is
+        used in many popular parallel port disk products such as the
+        SyQuest EZ drives, the Avatar Shark and the Imation SuperDisk.
+       
+*/
+
+/* Changes:
+
+        1.01    GRG 1998.05.06 init_proto, release_proto
+        1.02    Joshua b. Jore CPP(renamed), epat_connect, epat_disconnect
+
+*/
+
+#define EPAT_VERSION      "1.02"
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <asm/io.h>
+
+#include <linux/pata_parport.h>
+
+#define j44(a,b)               (((a>>4)&0x0f)+(b&0xf0))
+#define j53(a,b)               (((a>>3)&0x1f)+((b<<4)&0xe0))
+
+static int epatc8;
+
+module_param(epatc8, int, 0);
+MODULE_PARM_DESC(epatc8, "support for the Shuttle EP1284 chip, "
+       "used in any recent Imation SuperDisk (LS-120) drive.");
+
+/* cont =  0   IDE register file
+   cont =  1   IDE control registers
+   cont =  2   internal EPAT registers
+*/
+
+static int cont_map[3] = { 0x18, 0x10, 0 };
+
+static void epat_write_regr( PIA *pi, int cont, int regr, int val)
+
+{      int r;
+
+       r = regr + cont_map[cont];
+
+       switch (pi->mode) {
+
+       case 0:
+       case 1:
+       case 2: w0(0x60+r); w2(1); w0(val); w2(4);
+               break;
+
+       case 3:
+       case 4:
+       case 5: w3(0x40+r); w4(val);
+               break;
+
+       }
+}
+
+static int epat_read_regr( PIA *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();
+               return j44(a,b);
+
+       case 1: w0(0x40+r); w2(1); w2(4);
+               a = r1(); b = r2(); w0(0xff);
+               return j53(a,b);
+
+       case 2: w0(0x20+r); w2(1); w2(0x25);
+               a = r0(); w2(4);
+               return a;
+
+       case 3:
+       case 4:
+       case 5: w3(r); w2(0x24); a = r4(); w2(4);
+               return a;
+
+       }
+       return -1;      /* never gets here */
+}
+
+static void epat_read_block( PIA *pi, char * buf, int count )
+
+{      int  k, ph, a, b;
+
+       switch (pi->mode) {
+
+       case 0: w0(7); w2(1); w2(3); w0(0xff);
+               ph = 0;
+               for(k=0;k<count;k++) {
+                       if (k == count-1) w0(0xfd);
+                       w2(6+ph); a = r1();
+                       if (a & 8) b = a; 
+                         else { w2(4+ph); b = r1(); }
+                       buf[k] = j44(a,b);
+                       ph =  1 - ph;
+               }
+               w0(0); w2(4);
+               break;
+
+       case 1: w0(0x47); w2(1); w2(5); w0(0xff);
+               ph = 0;
+               for(k=0;k<count;k++) {
+                       if (k == count-1) w0(0xfd); 
+                       w2(4+ph);
+                       a = r1(); b = r2();
+                       buf[k] = j53(a,b);
+                       ph = 1 - ph;
+               }
+               w0(0); w2(4);
+               break;
+
+       case 2: w0(0x27); w2(1); w2(0x25); w0(0);
+               ph = 0;
+               for(k=0;k<count-1;k++) {
+                       w2(0x24+ph);
+                       buf[k] = r0();
+                       ph = 1 - ph;
+               }
+               w2(0x26); w2(0x27); buf[count-1] = r0(); 
+               w2(0x25); w2(4);
+               break;
+
+       case 3: w3(0x80); w2(0x24);
+               for(k=0;k<count-1;k++) buf[k] = r4();
+               w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
+               w2(4);
+               break;
+
+       case 4: w3(0x80); w2(0x24);
+               for(k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
+               buf[count-2] = r4();
+               w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
+               w2(4);
+               break;
+
+       case 5: w3(0x80); w2(0x24);
+               for(k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
+               for(k=count-4;k<count-1;k++) buf[k] = r4();
+               w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
+               w2(4);
+               break;
+
+       }
+}
+
+static void epat_write_block( PIA *pi, char * buf, int count )   
+
+{      int ph, k;
+
+       switch (pi->mode) {
+
+       case 0:
+       case 1:
+       case 2: w0(0x67); w2(1); w2(5);
+               ph = 0;
+               for(k=0;k<count;k++) {
+                       w0(buf[k]);
+                       w2(4+ph);
+                       ph = 1 - ph;
+               }
+               w2(7); w2(4);
+               break;
+
+       case 3: w3(0xc0); 
+               for(k=0;k<count;k++) w4(buf[k]);
+               w2(4);
+               break;
+
+       case 4: w3(0xc0); 
+               for(k=0;k<(count/2);k++) w4w(((u16 *)buf)[k]);
+               w2(4);
+               break;
+
+       case 5: w3(0xc0); 
+               for(k=0;k<(count/4);k++) w4l(((u32 *)buf)[k]);
+               w2(4);
+               break;
+
+       }
+}
+
+/* these macros access the EPAT registers in native addressing */
+
+#define        WR(r,v)         epat_write_regr(pi,2,r,v)
+#define        RR(r)           (epat_read_regr(pi,2,r))
+
+/* and these access the IDE task file */
+
+#define WRi(r,v)         epat_write_regr(pi,0,r,v)
+#define RRi(r)           (epat_read_regr(pi,0,r))
+
+/* FIXME:  the CPP stuff should be fixed to handle multiple EPATs on a chain */
+
+#define CPP(x)         w2(4);w0(0x22);w0(0xaa);w0(0x55);w0(0);w0(0xff);\
+                w0(0x87);w0(0x78);w0(x);w2(4);w2(5);w2(4);w0(0xff);
+
+static void epat_connect ( PIA *pi )
+
+{       pi->saved_r0 = r0();
+        pi->saved_r2 = r2();
+
+       /* Initialize the chip */
+       CPP(0);
+
+       if (epatc8) {
+               CPP(0x40);CPP(0xe0);
+               w0(0);w2(1);w2(4);
+               WR(0x8,0x12);WR(0xc,0x14);WR(0x12,0x10);
+               WR(0xe,0xf);WR(0xf,4);
+               /* WR(0xe,0xa);WR(0xf,4); */
+               WR(0xe,0xd);WR(0xf,0);
+               /* CPP(0x30); */
+       }
+
+        /* Connect to the chip */
+       CPP(0xe0);
+        w0(0);w2(1);w2(4); /* Idle into SPP */
+        if (pi->mode >= 3) {
+          w0(0);w2(1);w2(4);w2(0xc);
+          /* Request EPP */
+          w0(0x40);w2(6);w2(7);w2(4);w2(0xc);w2(4);
+        }
+
+       if (!epatc8) {
+               WR(8,0x10); WR(0xc,0x14); WR(0xa,0x38); WR(0x12,0x10);
+       }
+}
+
+static void epat_disconnect (PIA *pi)
+{      CPP(0x30);
+       w0(pi->saved_r0);
+       w2(pi->saved_r2);
+}
+
+static int epat_test_proto( PIA *pi, char * scratch, int verbose )
+
+{       int     k, j, f, cc;
+       int     e[2] = {0,0};
+
+        epat_connect(pi);
+       cc = RR(0xd);
+       epat_disconnect(pi);
+
+       epat_connect(pi);
+       for (j=0;j<2;j++) {
+           WRi(6,0xa0+j*0x10);
+            for (k=0;k<256;k++) {
+                WRi(2,k^0xaa);
+                WRi(3,k^0x55);
+                if (RRi(2) != (k^0xaa)) e[j]++;
+                }
+           }
+        epat_disconnect(pi);
+
+        f = 0;
+        epat_connect(pi);
+        WR(0x13,1); WR(0x13,0); WR(0xa,0x11);
+        epat_read_block(pi,scratch,512);
+       
+        for (k=0;k<256;k++) {
+            if ((scratch[2*k] & 0xff) != k) f++;
+            if ((scratch[2*k+1] & 0xff) != (0xff-k)) f++;
+        }
+        epat_disconnect(pi);
+
+        if (verbose)  {
+            printk("%s: epat: port 0x%x, mode %d, ccr %x, test=(%d,%d,%d)\n",
+                  pi->device,pi->port,pi->mode,cc,e[0],e[1],f);
+       }
+       
+        return (e[0] && e[1]) || f;
+}
+
+static void epat_log_adapter( PIA *pi, char * scratch, int verbose )
+
+{      int     ver;
+        char    *mode_string[6] = 
+                  {"4-bit","5/3","8-bit","EPP-8","EPP-16","EPP-32"};
+
+       epat_connect(pi);
+       WR(0xa,0x38);           /* read the version code */
+        ver = RR(0xb);
+        epat_disconnect(pi);
+
+       printk("%s: epat %s, Shuttle EPAT chip %x at 0x%x, ",
+               pi->device,EPAT_VERSION,ver,pi->port);
+       printk("mode %d (%s), delay %d\n",pi->mode,
+               mode_string[pi->mode],pi->delay);
+
+}
+
+static struct pi_protocol epat = {
+       .owner          = THIS_MODULE,
+       .name           = "epat",
+       .max_mode       = 6,
+       .epp_first      = 3,
+       .default_delay  = 1,
+       .max_units      = 1,
+       .write_regr     = epat_write_regr,
+       .read_regr      = epat_read_regr,
+       .write_block    = epat_write_block,
+       .read_block     = epat_read_block,
+       .connect        = epat_connect,
+       .disconnect     = epat_disconnect,
+       .test_proto     = epat_test_proto,
+       .log_adapter    = epat_log_adapter,
+};
+
+static int __init epat_init(void)
+{
+#ifdef CONFIG_PARIDE_EPATC8
+       epatc8 = 1;
+#endif
+       return paride_register(&epat);
+}
+
+static void __exit epat_exit(void)
+{
+       paride_unregister(&epat);
+}
+
+MODULE_LICENSE("GPL");
+module_init(epat_init)
+module_exit(epat_exit)
diff --git a/drivers/ata/pata_parport/epia.c b/drivers/ata/pata_parport/epia.c
new file mode 100644 (file)
index 0000000..417d5a3
--- /dev/null
@@ -0,0 +1,316 @@
+/* 
+        epia.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
+                              Under the terms of the GNU General Public License.
+
+        epia.c is a low-level protocol driver for Shuttle Technologies 
+       EPIA parallel to IDE adapter chip.  This device is now obsolete
+       and has been replaced with the EPAT chip, which is supported
+       by epat.c, however, some devices based on EPIA are still
+       available.
+
+*/
+
+/* Changes:
+
+        1.01    GRG 1998.05.06 init_proto, release_proto
+       1.02    GRG 1998.06.17 support older versions of EPIA
+
+*/
+
+#define EPIA_VERSION      "1.02"
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <asm/io.h>
+
+#include <linux/pata_parport.h>
+
+/* mode codes:  0  nybble reads on port 1, 8-bit writes
+                1  5/3 reads on ports 1 & 2, 8-bit writes
+                2  8-bit reads and writes
+                3  8-bit EPP mode
+               4  16-bit EPP
+               5  32-bit EPP
+*/
+
+#define j44(a,b)                (((a>>4)&0x0f)+(b&0xf0))
+#define j53(a,b)                (((a>>3)&0x1f)+((b<<4)&0xe0))
+
+/* cont =  0   IDE register file
+   cont =  1   IDE control registers
+*/
+
+static int cont_map[2] = { 0, 0x80 };
+
+static int epia_read_regr( PIA *pi, int cont, int regr )
+
+{       int     a, b, r;
+
+       regr += cont_map[cont];
+
+        switch (pi->mode)  {
+
+        case 0: r = regr^0x39;
+                w0(r); w2(1); w2(3); w0(r);
+                a = r1(); w2(1); b = r1(); w2(4);
+                return j44(a,b);
+
+        case 1: r = regr^0x31;
+                w0(r); w2(1); w0(r&0x37); 
+                w2(3); w2(5); w0(r|0xf0);
+                a = r1(); b = r2(); w2(4);
+                return j53(a,b);
+
+        case 2: r = regr^0x29;
+                w0(r); w2(1); w2(0X21); w2(0x23); 
+                a = r0(); w2(4);
+                return a;
+
+       case 3:
+       case 4:
+        case 5: w3(regr); w2(0x24); a = r4(); w2(4);
+                return a;
+
+        }
+        return -1;
+}       
+
+static void epia_write_regr( PIA *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)
+#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 ( PIA *pi  )
+
+{       pi->saved_r0 = r0();
+        pi->saved_r2 = r2();
+
+        w2(4); w0(0xa0); w0(0x50); w0(0xc0); w0(0x30); w0(0xa0); w0(0);
+        w2(1); w2(4);
+        if (pi->mode >= 3) { 
+                w0(0xa); w2(1); w2(4); w0(0x82); w2(4); w2(0xc); w2(4);
+                w2(0x24); w2(0x26); w2(4);
+        }
+        WR(0x86,8);  
+}
+
+static void epia_disconnect ( PIA *pi )
+
+{       /* WR(0x84,0x10); */
+        w0(pi->saved_r0);
+        w2(1); w2(4);
+        w0(pi->saved_r0);
+        w2(pi->saved_r2);
+} 
+
+static void epia_read_block( PIA *pi, char * buf, int count )
+
+{       int     k, ph, a, b;
+
+        switch (pi->mode) {
+
+        case 0: w0(0x81); w2(1); w2(3); w0(0xc1);
+                ph = 1;
+                for (k=0;k<count;k++) {
+                        w2(2+ph); a = r1();
+                        w2(4+ph); b = r1();
+                        buf[k] = j44(a,b);
+                        ph = 1 - ph;
+                } 
+                w0(0); w2(4);
+                break;
+
+        case 1: w0(0x91); w2(1); w0(0x10); w2(3); 
+                w0(0x51); w2(5); w0(0xd1); 
+                ph = 1;
+                for (k=0;k<count;k++) {
+                        w2(4+ph);
+                        a = r1(); b = r2();
+                        buf[k] = j53(a,b);
+                        ph = 1 - ph;
+                }
+                w0(0); w2(4);
+                break;
+
+        case 2: w0(0x89); w2(1); w2(0x23); w2(0x21); 
+                ph = 1;
+                for (k=0;k<count;k++) {
+                        w2(0x24+ph);
+                        buf[k] = r0();
+                        ph = 1 - ph;
+                }
+                w2(6); w2(4);
+                break;
+
+        case 3: if (count > 512) WR(0x84,3);
+               w3(0); w2(0x24);
+                for (k=0;k<count;k++) buf[k] = r4();
+                w2(4); WR(0x84,0);
+                break;
+
+        case 4: if (count > 512) WR(0x84,3);
+               w3(0); w2(0x24);
+               for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
+                w2(4); WR(0x84,0);
+                break;
+
+        case 5: if (count > 512) WR(0x84,3);
+               w3(0); w2(0x24);
+                for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
+                w2(4); WR(0x84,0);
+                break;
+
+        }
+}
+
+static void epia_write_block( PIA *pi, char * buf, int count )
+
+{       int     ph, k, last, d;
+
+        switch (pi->mode) {
+
+        case 0:
+        case 1:
+        case 2: w0(0xa1); w2(1); w2(3); w2(1); w2(5);
+                ph = 0;  last = 0x8000;
+                for (k=0;k<count;k++) {
+                        d = buf[k];
+                        if (d != last) { last = d; w0(d); }
+                        w2(4+ph);
+                        ph = 1 - ph;
+                }
+                w2(7); w2(4);
+                break;
+
+        case 3: if (count < 512) WR(0x84,1);
+               w3(0x40);
+                for (k=0;k<count;k++) w4(buf[k]);
+               if (count < 512) WR(0x84,0);
+                break;
+
+        case 4: if (count < 512) WR(0x84,1);
+               w3(0x40);
+                for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
+               if (count < 512) WR(0x84,0);
+                break;
+
+        case 5: if (count < 512) WR(0x84,1);
+               w3(0x40);
+                for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
+               if (count < 512) WR(0x84,0);
+                break;
+
+        }
+
+}
+
+static int epia_test_proto( PIA *pi, char * scratch, int verbose )
+
+{       int     j, k, f;
+       int     e[2] = {0,0};
+
+        epia_connect(pi);
+        for (j=0;j<2;j++) {
+            WR(6,0xa0+j*0x10);
+            for (k=0;k<256;k++) {
+                WR(2,k^0xaa);
+                WR(3,k^0x55);
+                if (RR(2) != (k^0xaa)) e[j]++;
+                }
+           WR(2,1); WR(3,1);
+            }
+        epia_disconnect(pi);
+
+        f = 0;
+        epia_connect(pi);
+        WR(0x84,8);
+        epia_read_block(pi,scratch,512);
+        for (k=0;k<256;k++) {
+            if ((scratch[2*k] & 0xff) != ((k+1) & 0xff)) f++;
+            if ((scratch[2*k+1] & 0xff) != ((-2-k) & 0xff)) f++;
+        }
+        WR(0x84,0);
+        epia_disconnect(pi);
+
+        if (verbose)  {
+            printk("%s: epia: port 0x%x, mode %d, test=(%d,%d,%d)\n",
+                   pi->device,pi->port,pi->mode,e[0],e[1],f);
+        }
+        
+        return (e[0] && e[1]) || f;
+
+}
+
+
+static void epia_log_adapter( PIA *pi, char * scratch, int verbose )
+
+{       char    *mode_string[6] = {"4-bit","5/3","8-bit",
+                                  "EPP-8","EPP-16","EPP-32"};
+
+        printk("%s: epia %s, Shuttle EPIA at 0x%x, ",
+                pi->device,EPIA_VERSION,pi->port);
+        printk("mode %d (%s), delay %d\n",pi->mode,
+               mode_string[pi->mode],pi->delay);
+
+}
+
+static struct pi_protocol epia = {
+       .owner          = THIS_MODULE,
+       .name           = "epia",
+       .max_mode       = 6,
+       .epp_first      = 3,
+       .default_delay  = 1,
+       .max_units      = 1,
+       .write_regr     = epia_write_regr,
+       .read_regr      = epia_read_regr,
+       .write_block    = epia_write_block,
+       .read_block     = epia_read_block,
+       .connect        = epia_connect,
+       .disconnect     = epia_disconnect,
+       .test_proto     = epia_test_proto,
+       .log_adapter    = epia_log_adapter,
+};
+
+static int __init epia_init(void)
+{
+       return paride_register(&epia);
+}
+
+static void __exit epia_exit(void)
+{
+       paride_unregister(&epia);
+}
+
+MODULE_LICENSE("GPL");
+module_init(epia_init)
+module_exit(epia_exit)
diff --git a/drivers/ata/pata_parport/fit2.c b/drivers/ata/pata_parport/fit2.c
new file mode 100644 (file)
index 0000000..3c7a106
--- /dev/null
@@ -0,0 +1,151 @@
+/* 
+        fit2.c        (c) 1998  Grant R. Guenther <grant@torque.net>
+                          Under the terms of the GNU General Public License.
+
+       fit2.c is a low-level protocol driver for the older version
+        of the Fidelity International Technology parallel port adapter.  
+       This adapter is used in their TransDisk 2000 and older TransDisk
+       3000 portable hard-drives.  As far as I can tell, this device
+       supports 4-bit mode _only_.  
+
+       Newer models of the FIT products use an enhanced protocol.
+       The "fit3" protocol module should support current drives.
+
+*/
+
+#define FIT2_VERSION      "1.0"
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <asm/io.h>
+
+#include <linux/pata_parport.h>
+
+#define j44(a,b)                (((a>>4)&0x0f)|(b&0xf0))
+
+/* cont = 0 - access the IDE register file 
+   cont = 1 - access the IDE command set 
+
+NB:  The FIT adapter does not appear to use the control registers.
+So, we map ALT_STATUS to STATUS and NO-OP writes to the device
+control register - this means that IDE reset will not work on these
+devices.
+
+*/
+
+static void  fit2_write_regr( PIA *pi, int cont, int regr, int val)
+
+{      if (cont == 1) return;
+       w2(0xc); w0(regr); w2(4); w0(val); w2(5); w0(0); w2(4);
+}
+
+static int fit2_read_regr( PIA *pi, int cont, int regr )
+
+{      int  a, b, r;
+
+       if (cont) {
+         if (regr != 6) return 0xff;
+         r = 7;
+       } else r = regr + 0x10;
+
+       w2(0xc); w0(r); w2(4); w2(5); 
+                w0(0); a = r1();
+                w0(1); b = r1();
+       w2(4);
+
+       return j44(a,b);
+
+}
+
+static void fit2_read_block( PIA *pi, char * buf, int count )
+
+{      int  k, a, b, c, d;
+
+       w2(0xc); w0(0x10);
+
+       for (k=0;k<count/4;k++) {
+
+               w2(4); w2(5);
+               w0(0); a = r1(); w0(1); b = r1();
+               w0(3); c = r1(); w0(2); d = r1(); 
+               buf[4*k+0] = j44(a,b);
+               buf[4*k+1] = j44(d,c);
+
+                w2(4); w2(5);
+                       a = r1(); w0(3); b = r1();
+                w0(1); c = r1(); w0(0); d = r1(); 
+                buf[4*k+2] = j44(d,c);
+                buf[4*k+3] = j44(a,b);
+
+       }
+
+       w2(4);
+
+}
+
+static void fit2_write_block( PIA *pi, char * buf, int count )
+
+{      int k;
+
+
+       w2(0xc); w0(0); 
+       for (k=0;k<count/2;k++) {
+               w2(4); w0(buf[2*k]); 
+               w2(5); w0(buf[2*k+1]);
+       }
+       w2(4);
+}
+
+static void fit2_connect ( PIA *pi  )
+
+{       pi->saved_r0 = r0();
+        pi->saved_r2 = r2();
+       w2(0xcc); 
+}
+
+static void fit2_disconnect ( PIA *pi )
+
+{       w0(pi->saved_r0);
+        w2(pi->saved_r2);
+} 
+
+static void fit2_log_adapter( PIA *pi, char * scratch, int verbose )
+
+{       printk("%s: fit2 %s, FIT 2000 adapter at 0x%x, delay %d\n",
+                pi->device,FIT2_VERSION,pi->port,pi->delay);
+
+}
+
+static struct pi_protocol fit2 = {
+       .owner          = THIS_MODULE,
+       .name           = "fit2",
+       .max_mode       = 1,
+       .epp_first      = 2,
+       .default_delay  = 1,
+       .max_units      = 1,
+       .write_regr     = fit2_write_regr,
+       .read_regr      = fit2_read_regr,
+       .write_block    = fit2_write_block,
+       .read_block     = fit2_read_block,
+       .connect        = fit2_connect,
+       .disconnect     = fit2_disconnect,
+       .log_adapter    = fit2_log_adapter,
+};
+
+static int __init fit2_init(void)
+{
+       return paride_register(&fit2);
+}
+
+static void __exit fit2_exit(void)
+{
+       paride_unregister(&fit2);
+}
+
+MODULE_LICENSE("GPL");
+module_init(fit2_init)
+module_exit(fit2_exit)
diff --git a/drivers/ata/pata_parport/fit3.c b/drivers/ata/pata_parport/fit3.c
new file mode 100644 (file)
index 0000000..cd95f4f
--- /dev/null
@@ -0,0 +1,211 @@
+/* 
+        fit3.c        (c) 1998  Grant R. Guenther <grant@torque.net>
+                          Under the terms of the GNU General Public License.
+
+       fit3.c is a low-level protocol driver for newer models 
+        of the Fidelity International Technology parallel port adapter.  
+       This adapter is used in their TransDisk 3000 portable 
+       hard-drives, as well as CD-ROM, PD-CD and other devices.
+
+       The TD-2000 and certain older devices use a different protocol.
+       Try the fit2 protocol module with them.
+
+        NB:  The FIT adapters do not appear to support the control 
+       registers.  So, we map ALT_STATUS to STATUS and NO-OP writes 
+       to the device control register - this means that IDE reset 
+       will not work on these devices.
+
+*/
+
+#define FIT3_VERSION      "1.0"
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <asm/io.h>
+
+#include <linux/pata_parport.h>
+
+#define j44(a,b)                (((a>>3)&0x0f)|((b<<1)&0xf0))
+
+#define w7(byte)                {out_p(7,byte);}
+#define r7()                    (in_p(7) & 0xff)
+
+/* cont = 0 - access the IDE register file 
+   cont = 1 - access the IDE command set 
+
+*/
+
+static void  fit3_write_regr( PIA *pi, int cont, int regr, int val)
+
+{      if (cont == 1) return;
+
+       switch (pi->mode) {
+
+       case 0:
+       case 1: w2(0xc); w0(regr); w2(0x8); w2(0xc); 
+               w0(val); w2(0xd); 
+               w0(0);   w2(0xc);
+               break;
+
+       case 2: w2(0xc); w0(regr); w2(0x8); w2(0xc);
+               w4(val); w4(0);
+               w2(0xc);
+               break;
+
+       }
+}
+
+static int fit3_read_regr( PIA *pi, int cont, int regr )
+
+{      int  a, b;
+
+       if (cont) {
+         if (regr != 6) return 0xff;
+         regr = 7;
+       } 
+
+       switch (pi->mode) {
+
+       case 0: w2(0xc); w0(regr + 0x10); w2(0x8); w2(0xc);
+               w2(0xd); a = r1();
+               w2(0xf); b = r1(); 
+               w2(0xc);
+               return j44(a,b);
+
+       case 1: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc);
+               w2(0xec); w2(0xee); w2(0xef); a = r0(); 
+               w2(0xc);
+               return a;
+
+       case 2: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc); 
+               w2(0xec); 
+               a = r4(); b = r4(); 
+               w2(0xc);
+               return a;
+
+       }
+       return -1; 
+
+}
+
+static void fit3_read_block( PIA *pi, char * buf, int count )
+
+{      int  k, a, b, c, d;
+
+       switch (pi->mode) {
+
+       case 0: w2(0xc); w0(0x10); w2(0x8); w2(0xc);
+               for (k=0;k<count/2;k++) {
+                   w2(0xd); a = r1();
+                   w2(0xf); b = r1();
+                   w2(0xc); c = r1();
+                   w2(0xe); d = r1();
+                   buf[2*k  ] = j44(a,b);
+                   buf[2*k+1] = j44(c,d);
+               }
+               w2(0xc);
+               break;
+
+       case 1: w2(0xc); w0(0x90); w2(0x8); w2(0xc); 
+               w2(0xec); w2(0xee);
+               for (k=0;k<count/2;k++) {
+                   w2(0xef); a = r0();
+                   w2(0xee); b = r0();
+                    buf[2*k  ] = a;
+                    buf[2*k+1] = b;
+               }
+               w2(0xec); 
+               w2(0xc);
+               break;
+
+       case 2: w2(0xc); w0(0x90); w2(0x8); w2(0xc); 
+                w2(0xec);
+               for (k=0;k<count;k++) buf[k] = r4();
+                w2(0xc);
+               break;
+
+       }
+}
+
+static void fit3_write_block( PIA *pi, char * buf, int count )
+
+{      int k;
+
+        switch (pi->mode) {
+
+       case 0:
+        case 1: w2(0xc); w0(0); w2(0x8); w2(0xc);
+                for (k=0;k<count/2;k++) {
+                   w0(buf[2*k  ]); w2(0xd);
+                   w0(buf[2*k+1]); w2(0xc);
+               }
+               break;
+
+        case 2: w2(0xc); w0(0); w2(0x8); w2(0xc); 
+                for (k=0;k<count;k++) w4(buf[k]);
+                w2(0xc);
+               break;
+       }
+}
+
+static void fit3_connect ( PIA *pi  )
+
+{       pi->saved_r0 = r0();
+        pi->saved_r2 = r2();
+       w2(0xc); w0(0); w2(0xa);
+       if (pi->mode == 2) { 
+               w2(0xc); w0(0x9); w2(0x8); w2(0xc); 
+               }
+}
+
+static void fit3_disconnect ( PIA *pi )
+
+{       w2(0xc); w0(0xa); w2(0x8); w2(0xc);
+       w0(pi->saved_r0);
+        w2(pi->saved_r2);
+} 
+
+static void fit3_log_adapter( PIA *pi, char * scratch, int verbose )
+
+{       char    *mode_string[3] = {"4-bit","8-bit","EPP"};
+
+       printk("%s: fit3 %s, FIT 3000 adapter at 0x%x, "
+              "mode %d (%s), delay %d\n",
+                pi->device,FIT3_VERSION,pi->port,
+               pi->mode,mode_string[pi->mode],pi->delay);
+
+}
+
+static struct pi_protocol fit3 = {
+       .owner          = THIS_MODULE,
+       .name           = "fit3",
+       .max_mode       = 3,
+       .epp_first      = 2,
+       .default_delay  = 1,
+       .max_units      = 1,
+       .write_regr     = fit3_write_regr,
+       .read_regr      = fit3_read_regr,
+       .write_block    = fit3_write_block,
+       .read_block     = fit3_read_block,
+       .connect        = fit3_connect,
+       .disconnect     = fit3_disconnect,
+       .log_adapter    = fit3_log_adapter,
+};
+
+static int __init fit3_init(void)
+{
+       return paride_register(&fit3);
+}
+
+static void __exit fit3_exit(void)
+{
+       paride_unregister(&fit3);
+}
+
+MODULE_LICENSE("GPL");
+module_init(fit3_init)
+module_exit(fit3_exit)
diff --git a/drivers/ata/pata_parport/friq.c b/drivers/ata/pata_parport/friq.c
new file mode 100644 (file)
index 0000000..da1d0cb
--- /dev/null
@@ -0,0 +1,276 @@
+/* 
+       friq.c  (c) 1998    Grant R. Guenther <grant@torque.net>
+                           Under the terms of the GNU General Public License
+
+       friq.c is a low-level protocol driver for the Freecom "IQ"
+       parallel port IDE adapter.   Early versions of this adapter
+       use the 'frpw' protocol.
+       
+       Freecom uses this adapter in a battery powered external 
+       CD-ROM drive.  It is also used in LS-120 drives by
+       Maxell and Panasonic, and other devices.
+
+       The battery powered drive requires software support to
+       control the power to the drive.  This module enables the
+       drive power when the high level driver (pcd) is loaded
+       and disables it when the module is unloaded.  Note, if
+       the friq module is built in to the kernel, the power
+       will never be switched off, so other means should be
+       used to conserve battery power.
+
+*/
+
+/* Changes:
+
+       1.01    GRG 1998.12.20   Added support for soft power switch
+*/
+
+#define        FRIQ_VERSION    "1.01" 
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <asm/io.h>
+
+#include <linux/pata_parport.h>
+
+#define CMD(x)         w2(4);w0(0xff);w0(0xff);w0(0x73);w0(0x73);\
+                       w0(0xc9);w0(0xc9);w0(0x26);w0(0x26);w0(x);w0(x);
+
+#define j44(l,h)       (((l>>4)&0x0f)|(h&0xf0))
+
+/* cont = 0 - access the IDE register file 
+   cont = 1 - access the IDE command set 
+*/
+
+static int  cont_map[2] = { 0x08, 0x10 };
+
+static int friq_read_regr( PIA *pi, int cont, int regr )
+
+{      int     h,l,r;
+
+       r = regr + cont_map[cont];
+
+       CMD(r);
+       w2(6); l = r1();
+       w2(4); h = r1();
+       w2(4); 
+
+       return j44(l,h);
+
+}
+
+static void friq_write_regr( PIA *pi, int cont, int regr, int val)
+
+{      int r;
+
+        r = regr + cont_map[cont];
+
+       CMD(r);
+       w0(val);
+       w2(5);w2(7);w2(5);w2(4);
+}
+
+static void friq_read_block_int( PIA *pi, char * buf, int count, int regr )
+
+{       int     h, l, k, ph;
+
+        switch(pi->mode) {
+
+        case 0: CMD(regr); 
+                for (k=0;k<count;k++) {
+                        w2(6); l = r1();
+                        w2(4); h = r1();
+                        buf[k] = j44(l,h);
+                }
+                w2(4);
+                break;
+
+        case 1: ph = 2;
+                CMD(regr+0xc0); 
+                w0(0xff);
+                for (k=0;k<count;k++) {
+                        w2(0xa4 + ph); 
+                        buf[k] = r0();
+                        ph = 2 - ph;
+                } 
+                w2(0xac); w2(0xa4); w2(4);
+                break;
+
+       case 2: CMD(regr+0x80);
+               for (k=0;k<count-2;k++) buf[k] = r4();
+               w2(0xac); w2(0xa4);
+               buf[count-2] = r4();
+               buf[count-1] = r4();
+               w2(4);
+               break;
+
+       case 3: CMD(regr+0x80);
+                for (k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
+                w2(0xac); w2(0xa4);
+                buf[count-2] = r4();
+                buf[count-1] = r4();
+                w2(4);
+                break;
+
+       case 4: CMD(regr+0x80);
+                for (k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
+                buf[count-4] = r4();
+                buf[count-3] = r4();
+                w2(0xac); w2(0xa4);
+                buf[count-2] = r4();
+                buf[count-1] = r4();
+                w2(4);
+                break;
+
+        }
+}
+
+static void friq_read_block( PIA *pi, char * buf, int count)
+
+{      friq_read_block_int(pi,buf,count,0x08);
+}
+
+static void friq_write_block( PIA *pi, char * buf, int count )
+{      int     k;
+
+       switch(pi->mode) {
+
+       case 0:
+       case 1: CMD(8); w2(5);
+               for (k=0;k<count;k++) {
+                       w0(buf[k]);
+                       w2(7);w2(5);
+               }
+               w2(4);
+               break;
+
+       case 2: CMD(0xc8); w2(5);
+               for (k=0;k<count;k++) w4(buf[k]);
+               w2(4);
+               break;
+
+        case 3: CMD(0xc8); w2(5);
+                for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
+                w2(4);
+                break;
+
+        case 4: CMD(0xc8); w2(5);
+                for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
+                w2(4);
+                break;
+       }
+}
+
+static void friq_connect ( PIA *pi  )
+
+{       pi->saved_r0 = r0();
+        pi->saved_r2 = r2();
+       w2(4);
+}
+
+static void friq_disconnect ( PIA *pi )
+
+{       CMD(0x20);
+       w0(pi->saved_r0);
+        w2(pi->saved_r2);
+} 
+
+static int friq_test_proto( PIA *pi, char * scratch, int verbose )
+
+{       int     j, k, r;
+       int     e[2] = {0,0};
+
+       pi->saved_r0 = r0();    
+       w0(0xff); udelay(20); CMD(0x3d); /* turn the power on */
+       udelay(500);
+       w0(pi->saved_r0);
+
+       friq_connect(pi);
+       for (j=0;j<2;j++) {
+                friq_write_regr(pi,0,6,0xa0+j*0x10);
+                for (k=0;k<256;k++) {
+                        friq_write_regr(pi,0,2,k^0xaa);
+                        friq_write_regr(pi,0,3,k^0x55);
+                        if (friq_read_regr(pi,0,2) != (k^0xaa)) e[j]++;
+                        }
+                }
+       friq_disconnect(pi);
+
+       friq_connect(pi);
+        friq_read_block_int(pi,scratch,512,0x10);
+        r = 0;
+        for (k=0;k<128;k++) if (scratch[k] != k) r++;
+       friq_disconnect(pi);
+
+        if (verbose)  {
+            printk("%s: friq: port 0x%x, mode %d, test=(%d,%d,%d)\n",
+                   pi->device,pi->port,pi->mode,e[0],e[1],r);
+        }
+
+        return (r || (e[0] && e[1]));
+}
+
+
+static void friq_log_adapter( PIA *pi, char * scratch, int verbose )
+
+{       char    *mode_string[6] = {"4-bit","8-bit",
+                                  "EPP-8","EPP-16","EPP-32"};
+
+        printk("%s: friq %s, Freecom IQ ASIC-2 adapter at 0x%x, ", pi->device,
+               FRIQ_VERSION,pi->port);
+        printk("mode %d (%s), delay %d\n",pi->mode,
+               mode_string[pi->mode],pi->delay);
+
+       pi->private = 1;
+       friq_connect(pi);
+       CMD(0x9e);              /* disable sleep timer */
+       friq_disconnect(pi);
+
+}
+
+static void friq_release_proto( PIA *pi)
+{
+       if (pi->private) {              /* turn off the power */
+               friq_connect(pi);
+               CMD(0x1d); CMD(0x1e);
+               friq_disconnect(pi);
+               pi->private = 0;
+       }
+}
+
+static struct pi_protocol friq = {
+       .owner          = THIS_MODULE,
+       .name           = "friq",
+       .max_mode       = 5,
+       .epp_first      = 2,
+       .default_delay  = 1,
+       .max_units      = 1,
+       .write_regr     = friq_write_regr,
+       .read_regr      = friq_read_regr,
+       .write_block    = friq_write_block,
+       .read_block     = friq_read_block,
+       .connect        = friq_connect,
+       .disconnect     = friq_disconnect,
+       .test_proto     = friq_test_proto,
+       .log_adapter    = friq_log_adapter,
+       .release_proto  = friq_release_proto,
+};
+
+static int __init friq_init(void)
+{
+       return paride_register(&friq);
+}
+
+static void __exit friq_exit(void)
+{
+       paride_unregister(&friq);
+}
+
+MODULE_LICENSE("GPL");
+module_init(friq_init)
+module_exit(friq_exit)
diff --git a/drivers/ata/pata_parport/frpw.c b/drivers/ata/pata_parport/frpw.c
new file mode 100644 (file)
index 0000000..7bc8fa1
--- /dev/null
@@ -0,0 +1,313 @@
+/* 
+       frpw.c  (c) 1996-8  Grant R. Guenther <grant@torque.net>
+                           Under the terms of the GNU General Public License
+
+       frpw.c is a low-level protocol driver for the Freecom "Power"
+       parallel port IDE adapter.
+       
+       Some applications of this adapter may require a "printer" reset
+       prior to loading the driver.  This can be done by loading and
+       unloading the "lp" driver, or it can be done by this driver
+       if you define FRPW_HARD_RESET.  The latter is not recommended
+       as it may upset devices on other ports.
+
+*/
+
+/* Changes:
+
+        1.01    GRG 1998.05.06 init_proto, release_proto
+                              fix chip detect
+                              added EPP-16 and EPP-32
+       1.02    GRG 1998.09.23 added hard reset to initialisation process
+       1.03    GRG 1998.12.14 made hard reset conditional
+
+*/
+
+#define        FRPW_VERSION    "1.03" 
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <asm/io.h>
+
+#include <linux/pata_parport.h>
+
+#define cec4           w2(0xc);w2(0xe);w2(0xe);w2(0xc);w2(4);w2(4);w2(4);
+#define j44(l,h)       (((l>>4)&0x0f)|(h&0xf0))
+
+/* cont = 0 - access the IDE register file 
+   cont = 1 - access the IDE command set 
+*/
+
+static int  cont_map[2] = { 0x08, 0x10 };
+
+static int frpw_read_regr( PIA *pi, int cont, int regr )
+
+{      int     h,l,r;
+
+       r = regr + cont_map[cont];
+
+       w2(4);
+       w0(r); cec4;
+       w2(6); l = r1();
+       w2(4); h = r1();
+       w2(4); 
+
+       return j44(l,h);
+
+}
+
+static void frpw_write_regr( PIA *pi, int cont, int regr, int val)
+
+{      int r;
+
+        r = regr + cont_map[cont];
+
+       w2(4); w0(r); cec4; 
+       w0(val);
+       w2(5);w2(7);w2(5);w2(4);
+}
+
+static void frpw_read_block_int( PIA *pi, char * buf, int count, int regr )
+
+{       int     h, l, k, ph;
+
+        switch(pi->mode) {
+
+        case 0: w2(4); w0(regr); cec4;
+                for (k=0;k<count;k++) {
+                        w2(6); l = r1();
+                        w2(4); h = r1();
+                        buf[k] = j44(l,h);
+                }
+                w2(4);
+                break;
+
+        case 1: ph = 2;
+                w2(4); w0(regr + 0xc0); cec4;
+                w0(0xff);
+                for (k=0;k<count;k++) {
+                        w2(0xa4 + ph); 
+                        buf[k] = r0();
+                        ph = 2 - ph;
+                } 
+                w2(0xac); w2(0xa4); w2(4);
+                break;
+
+        case 2: w2(4); w0(regr + 0x80); cec4;
+                for (k=0;k<count;k++) buf[k] = r4();
+                w2(0xac); w2(0xa4);
+                w2(4);
+                break;
+
+       case 3: w2(4); w0(regr + 0x80); cec4;
+               for (k=0;k<count-2;k++) buf[k] = r4();
+               w2(0xac); w2(0xa4);
+               buf[count-2] = r4();
+               buf[count-1] = r4();
+               w2(4);
+               break;
+
+       case 4: w2(4); w0(regr + 0x80); cec4;
+                for (k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
+                w2(0xac); w2(0xa4);
+                buf[count-2] = r4();
+                buf[count-1] = r4();
+                w2(4);
+                break;
+
+       case 5: w2(4); w0(regr + 0x80); cec4;
+                for (k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
+                buf[count-4] = r4();
+                buf[count-3] = r4();
+                w2(0xac); w2(0xa4);
+                buf[count-2] = r4();
+                buf[count-1] = r4();
+                w2(4);
+                break;
+
+        }
+}
+
+static void frpw_read_block( PIA *pi, char * buf, int count)
+
+{      frpw_read_block_int(pi,buf,count,0x08);
+}
+
+static void frpw_write_block( PIA *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 ( PIA *pi  )
+
+{       pi->saved_r0 = r0();
+        pi->saved_r2 = r2();
+       w2(4);
+}
+
+static void frpw_disconnect ( PIA *pi )
+
+{       w2(4); w0(0x20); cec4;
+       w0(pi->saved_r0);
+        w2(pi->saved_r2);
+} 
+
+/* Stub logic to see if PNP string is available - used to distinguish
+   between the Xilinx and ASIC implementations of the Freecom adapter.
+*/
+
+static int frpw_test_pnp ( PIA *pi )
+
+/*  returns chip_type:   0 = Xilinx, 1 = ASIC   */
+
+{      int olddelay, a, b;
+
+#ifdef FRPW_HARD_RESET
+        w0(0); w2(8); udelay(50); w2(0xc);   /* parallel bus reset */
+        mdelay(1500);
+#endif
+
+       olddelay = pi->delay;
+       pi->delay = 10;
+
+       pi->saved_r0 = r0();
+        pi->saved_r2 = r2();
+       
+       w2(4); w0(4); w2(6); w2(7);
+       a = r1() & 0xff; w2(4); b = r1() & 0xff;
+       w2(0xc); w2(0xe); w2(4);
+
+       pi->delay = olddelay;
+        w0(pi->saved_r0);
+        w2(pi->saved_r2);
+
+       return ((~a&0x40) && (b&0x40));
+} 
+
+/* We use the pi->private to remember the result of the PNP test.
+   To make this work, private = port*2 + chip.  Yes, I know it's
+   a hack :-(
+*/
+
+static int frpw_test_proto( PIA *pi, char * scratch, int verbose )
+
+{       int     j, k, r;
+       int     e[2] = {0,0};
+
+       if ((pi->private>>1) != pi->port)
+          pi->private = frpw_test_pnp(pi) + 2*pi->port;
+
+       if (((pi->private%2) == 0) && (pi->mode > 2)) {
+          if (verbose) 
+               printk("%s: frpw: Xilinx does not support mode %d\n",
+                       pi->device, pi->mode);
+          return 1;
+       }
+
+       if (((pi->private%2) == 1) && (pi->mode == 2)) {
+          if (verbose)
+               printk("%s: frpw: ASIC does not support mode 2\n",
+                       pi->device);
+          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);
+
+        if (verbose)  {
+            printk("%s: frpw: port 0x%x, chip %ld, mode %d, test=(%d,%d,%d)\n",
+                   pi->device,pi->port,(pi->private%2),pi->mode,e[0],e[1],r);
+        }
+
+        return (r || (e[0] && e[1]));
+}
+
+
+static void frpw_log_adapter( PIA *pi, char * scratch, int verbose )
+
+{       char    *mode_string[6] = {"4-bit","8-bit","EPP",
+                                  "EPP-8","EPP-16","EPP-32"};
+
+        printk("%s: frpw %s, Freecom (%s) adapter at 0x%x, ", pi->device,
+               FRPW_VERSION,((pi->private%2) == 0)?"Xilinx":"ASIC",pi->port);
+        printk("mode %d (%s), delay %d\n",pi->mode,
+               mode_string[pi->mode],pi->delay);
+
+}
+
+static struct pi_protocol frpw = {
+       .owner          = THIS_MODULE,
+       .name           = "frpw",
+       .max_mode       = 6,
+       .epp_first      = 2,
+       .default_delay  = 2,
+       .max_units      = 1,
+       .write_regr     = frpw_write_regr,
+       .read_regr      = frpw_read_regr,
+       .write_block    = frpw_write_block,
+       .read_block     = frpw_read_block,
+       .connect        = frpw_connect,
+       .disconnect     = frpw_disconnect,
+       .test_proto     = frpw_test_proto,
+       .log_adapter    = frpw_log_adapter,
+};
+
+static int __init frpw_init(void)
+{
+       return paride_register(&frpw);
+}
+
+static void __exit frpw_exit(void)
+{
+       paride_unregister(&frpw);
+}
+
+MODULE_LICENSE("GPL");
+module_init(frpw_init)
+module_exit(frpw_exit)
diff --git a/drivers/ata/pata_parport/kbic.c b/drivers/ata/pata_parport/kbic.c
new file mode 100644 (file)
index 0000000..f0960eb
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+        kbic.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
+                              Under the terms of the GNU General Public License.
+
+        This is a low-level driver for the KBIC-951A and KBIC-971A
+        parallel to IDE adapter chips from KingByte Information Systems.
+
+       The chips are almost identical, however, the wakeup code 
+       required for the 971A interferes with the correct operation of
+        the 951A, so this driver registers itself twice, once for
+       each chip.
+
+*/
+
+/* Changes:
+
+        1.01    GRG 1998.05.06 init_proto, release_proto
+
+*/
+
+#define KBIC_VERSION      "1.01"
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <asm/io.h>
+
+#include <linux/pata_parport.h>
+
+#define r12w()                 (delay_p,inw(pi->port+1)&0xffff) 
+
+#define j44(a,b)                ((((a>>4)&0x0f)|(b&0xf0))^0x88)
+#define j53(w)                  (((w>>3)&0x1f)|((w>>4)&0xe0))
+
+
+/* cont = 0 - access the IDE register file 
+   cont = 1 - access the IDE command set 
+*/
+
+static int  cont_map[2] = { 0x80, 0x40 };
+
+static int kbic_read_regr( PIA *pi, int cont, int regr )
+
+{       int     a, b, s;
+
+        s = cont_map[cont];
+
+       switch (pi->mode) {
+
+       case 0: w0(regr|0x18|s); w2(4); w2(6); w2(4); w2(1); w0(8);
+               a = r1(); w0(0x28); b = r1(); w2(4);
+               return j44(a,b);
+
+       case 1: w0(regr|0x38|s); w2(4); w2(6); w2(4); w2(5); w0(8);
+               a = r12w(); w2(4);
+               return j53(a);
+
+       case 2: w0(regr|0x08|s); w2(4); w2(6); w2(4); w2(0xa5); w2(0xa1);
+               a = r0(); w2(4);
+                       return a;
+
+       case 3:
+       case 4:
+       case 5: w0(0x20|s); w2(4); w2(6); w2(4); w3(regr);
+               a = r4(); b = r4(); w2(4); w2(0); w2(4);
+               return a;
+
+       }
+       return -1;
+}       
+
+static void  kbic_write_regr( PIA *pi, int cont, int regr, int val)
+
+{       int  s;
+
+        s = cont_map[cont];
+
+        switch (pi->mode) {
+
+       case 0: 
+        case 1:
+       case 2: w0(regr|0x10|s); w2(4); w2(6); w2(4); 
+               w0(val); w2(5); w2(4);
+               break;
+
+       case 3:
+       case 4:
+       case 5: w0(0x20|s); w2(4); w2(6); w2(4); w3(regr);
+               w4(val); w4(val);
+               w2(4); w2(0); w2(4);
+                break;
+
+       }
+}
+
+static void k951_connect ( PIA *pi  )
+
+{      pi->saved_r0 = r0();
+        pi->saved_r2 = r2();
+        w2(4); 
+}
+
+static void k951_disconnect ( PIA *pi )
+
+{              w0(pi->saved_r0);
+        w2(pi->saved_r2);
+}
+
+#define        CCP(x)  w2(0xc4);w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);\
+               w0(0x78);w0(x);w2(0xc5);w2(0xc4);w0(0xff);
+
+static void k971_connect ( PIA *pi  )
+
+{      pi->saved_r0 = r0();
+        pi->saved_r2 = r2();
+       CCP(0x20);
+        w2(4); 
+}
+
+static void k971_disconnect ( PIA *pi )
+
+{       CCP(0x30);
+       w0(pi->saved_r0);
+        w2(pi->saved_r2);
+}
+
+/* counts must be congruent to 0 MOD 4, but all known applications
+   have this property.
+*/
+
+static void kbic_read_block( PIA *pi, char * buf, int count )
+
+{       int     k, a, b;
+
+        switch (pi->mode) {
+
+        case 0: w0(0x98); w2(4); w2(6); w2(4);
+                for (k=0;k<count/2;k++) {
+                       w2(1); w0(8);    a = r1();
+                              w0(0x28); b = r1();
+                       buf[2*k]   = j44(a,b);
+                       w2(5);           b = r1();
+                              w0(8);    a = r1();
+                       buf[2*k+1] = j44(a,b);
+                       w2(4);
+                } 
+                break;
+
+        case 1: w0(0xb8); w2(4); w2(6); w2(4); 
+                for (k=0;k<count/4;k++) {
+                        w0(0xb8); 
+                       w2(4); w2(5); 
+                        w0(8);    buf[4*k]   = j53(r12w());
+                       w0(0xb8); buf[4*k+1] = j53(r12w());
+                       w2(4); w2(5);
+                                 buf[4*k+3] = j53(r12w());
+                       w0(8);    buf[4*k+2] = j53(r12w());
+                }
+                w2(4);
+                break;
+
+        case 2: w0(0x88); w2(4); w2(6); w2(4);
+                for (k=0;k<count/2;k++) {
+                        w2(0xa0); w2(0xa1); buf[2*k] = r0();
+                        w2(0xa5); buf[2*k+1] = r0();
+                }
+                w2(4);
+                break;
+
+        case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
+                for (k=0;k<count;k++) buf[k] = r4();
+                w2(4); w2(0); w2(4);
+                break;
+
+       case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
+                for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
+                w2(4); w2(0); w2(4);
+                break;
+
+        case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
+                for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
+                w2(4); w2(0); w2(4);
+                break;
+
+
+        }
+}
+
+static void kbic_write_block( PIA *pi, char * buf, int count )
+
+{       int     k;
+
+        switch (pi->mode) {
+
+        case 0:
+        case 1:
+        case 2: w0(0x90); w2(4); w2(6); w2(4); 
+               for(k=0;k<count/2;k++) {
+                       w0(buf[2*k+1]); w2(0); w2(4); 
+                       w0(buf[2*k]);   w2(5); w2(4); 
+               }
+               break;
+
+        case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
+               for(k=0;k<count/2;k++) {
+                       w4(buf[2*k+1]); 
+                        w4(buf[2*k]);
+                }
+               w2(4); w2(0); w2(4);
+               break;
+
+       case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
+                for(k=0;k<count/2;k++) w4w(pi_swab16(buf,k));
+                w2(4); w2(0); w2(4);
+                break;
+
+        case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
+                for(k=0;k<count/4;k++) w4l(pi_swab32(buf,k));
+                w2(4); w2(0); w2(4);
+                break;
+
+        }
+
+}
+
+static void kbic_log_adapter( PIA *pi, char * scratch, 
+                             int verbose, char * chip )
+
+{       char    *mode_string[6] = {"4-bit","5/3","8-bit",
+                                  "EPP-8","EPP_16","EPP-32"};
+
+        printk("%s: kbic %s, KingByte %s at 0x%x, ",
+                pi->device,KBIC_VERSION,chip,pi->port);
+        printk("mode %d (%s), delay %d\n",pi->mode,
+               mode_string[pi->mode],pi->delay);
+
+}
+
+static void k951_log_adapter( PIA *pi, char * scratch, int verbose )
+
+{      kbic_log_adapter(pi,scratch,verbose,"KBIC-951A");
+}
+
+static void k971_log_adapter( PIA *pi, char * scratch, int verbose )
+
+{       kbic_log_adapter(pi,scratch,verbose,"KBIC-971A");
+}
+
+static struct pi_protocol k951 = {
+       .owner          = THIS_MODULE,
+       .name           = "k951",
+       .max_mode       = 6,
+       .epp_first      = 3,
+       .default_delay  = 1,
+       .max_units      = 1,
+       .write_regr     = kbic_write_regr,
+       .read_regr      = kbic_read_regr,
+       .write_block    = kbic_write_block,
+       .read_block     = kbic_read_block,
+       .connect        = k951_connect,
+       .disconnect     = k951_disconnect,
+       .log_adapter    = k951_log_adapter,
+};
+
+static struct pi_protocol k971 = {
+       .owner          = THIS_MODULE,
+       .name           = "k971",
+       .max_mode       = 6,
+       .epp_first      = 3,
+       .default_delay  = 1,
+       .max_units      = 1,
+       .write_regr     = kbic_write_regr,
+       .read_regr      = kbic_read_regr,
+       .write_block    = kbic_write_block,
+       .read_block     = kbic_read_block,
+       .connect        = k971_connect,
+       .disconnect     = k971_disconnect,
+       .log_adapter    = k971_log_adapter,
+};
+
+static int __init kbic_init(void)
+{
+       int rv;
+
+       rv = paride_register(&k951);
+       if (rv < 0)
+               return rv;
+       rv = paride_register(&k971);
+       if (rv < 0)
+               paride_unregister(&k951);
+       return rv;
+}
+
+static void __exit kbic_exit(void)
+{
+       paride_unregister(&k951);
+       paride_unregister(&k971);
+}
+
+MODULE_LICENSE("GPL");
+module_init(kbic_init)
+module_exit(kbic_exit)
diff --git a/drivers/ata/pata_parport/ktti.c b/drivers/ata/pata_parport/ktti.c
new file mode 100644 (file)
index 0000000..fc4f707
--- /dev/null
@@ -0,0 +1,128 @@
+/* 
+        ktti.c        (c) 1998  Grant R. Guenther <grant@torque.net>
+                          Under the terms of the GNU General Public License.
+
+       ktti.c is a low-level protocol driver for the KT Technology
+       parallel port adapter.  This adapter is used in the "PHd" 
+        portable hard-drives.  As far as I can tell, this device
+       supports 4-bit mode _only_.  
+
+*/
+
+#define KTTI_VERSION      "1.0"
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <asm/io.h>
+
+#include <linux/pata_parport.h>
+
+#define j44(a,b)                (((a>>4)&0x0f)|(b&0xf0))
+
+/* cont = 0 - access the IDE register file 
+   cont = 1 - access the IDE command set 
+*/
+
+static int  cont_map[2] = { 0x10, 0x08 };
+
+static void  ktti_write_regr( PIA *pi, int cont, int regr, int val)
+
+{      int r;
+
+       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);
+}
+
+static int ktti_read_regr( PIA *pi, int cont, int regr )
+
+{      int  a, b, r;
+
+        r = regr + cont_map[cont];
+
+        w0(r); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9); 
+       a = r1(); w2(0xc);  b = r1(); w2(9); w2(0xc); w2(9);
+       return j44(a,b);
+
+}
+
+static void ktti_read_block( PIA *pi, char * buf, int count )
+
+{      int  k, a, b;
+
+       for (k=0;k<count/2;k++) {
+               w0(0x10); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9);
+               a = r1(); w2(0xc); b = r1(); w2(9);
+               buf[2*k] = j44(a,b);
+               a = r1(); w2(0xc); b = r1(); w2(9);
+               buf[2*k+1] = j44(a,b);
+       }
+}
+
+static void ktti_write_block( PIA *pi, char * buf, int count )
+
+{      int k;
+
+       for (k=0;k<count/2;k++) {
+               w0(0x10); w2(0xb); w2(0xa); w2(3); w2(6);
+               w0(buf[2*k]); w2(3);
+               w0(buf[2*k+1]); w2(6);
+               w2(0xb);
+       }
+}
+
+static void ktti_connect ( PIA *pi  )
+
+{       pi->saved_r0 = r0();
+        pi->saved_r2 = r2();
+       w2(0xb); w2(0xa); w0(0); w2(3); w2(6);  
+}
+
+static void ktti_disconnect ( PIA *pi )
+
+{       w2(0xb); w2(0xa); w0(0xa0); w2(3); w2(4);
+       w0(pi->saved_r0);
+        w2(pi->saved_r2);
+} 
+
+static void ktti_log_adapter( PIA *pi, char * scratch, int verbose )
+
+{       printk("%s: ktti %s, KT adapter at 0x%x, delay %d\n",
+                pi->device,KTTI_VERSION,pi->port,pi->delay);
+
+}
+
+static struct pi_protocol ktti = {
+       .owner          = THIS_MODULE,
+       .name           = "ktti",
+       .max_mode       = 1,
+       .epp_first      = 2,
+       .default_delay  = 1,
+       .max_units      = 1,
+       .write_regr     = ktti_write_regr,
+       .read_regr      = ktti_read_regr,
+       .write_block    = ktti_write_block,
+       .read_block     = ktti_read_block,
+       .connect        = ktti_connect,
+       .disconnect     = ktti_disconnect,
+       .log_adapter    = ktti_log_adapter,
+};
+
+static int __init ktti_init(void)
+{
+       return paride_register(&ktti);
+}
+
+static void __exit ktti_exit(void)
+{
+       paride_unregister(&ktti);
+}
+
+MODULE_LICENSE("GPL");
+module_init(ktti_init)
+module_exit(ktti_exit)
diff --git a/drivers/ata/pata_parport/on20.c b/drivers/ata/pata_parport/on20.c
new file mode 100644 (file)
index 0000000..995fc41
--- /dev/null
@@ -0,0 +1,153 @@
+/* 
+       on20.c  (c) 1996-8  Grant R. Guenther <grant@torque.net>
+                           Under the terms of the GNU General Public License.
+
+        on20.c is a low-level protocol driver for the
+        Onspec 90c20 parallel to IDE adapter. 
+*/
+
+/* Changes:
+
+        1.01    GRG 1998.05.06 init_proto, release_proto
+
+*/
+
+#define        ON20_VERSION    "1.01"
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <asm/io.h>
+
+#include <linux/pata_parport.h>
+
+#define op(f)  w2(4);w0(f);w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4);
+#define vl(v)  w2(4);w0(v);w2(5);w2(7);w2(5);w2(4);
+
+#define j44(a,b)  (((a>>4)&0x0f)|(b&0xf0))
+
+/* cont = 0 - access the IDE register file 
+   cont = 1 - access the IDE command set 
+*/
+
+static int on20_read_regr( PIA *pi, int cont, int regr )
+
+{      int h,l, r ;
+
+        r = (regr<<2) + 1 + cont;
+
+        op(1); vl(r); op(0);
+
+       switch (pi->mode)  {
+
+        case 0:  w2(4); w2(6); l = r1();
+                 w2(4); w2(6); h = r1();
+                 w2(4); w2(6); w2(4); w2(6); w2(4);
+                return j44(l,h);
+
+       case 1:  w2(4); w2(0x26); r = r0(); 
+                 w2(4); w2(0x26); w2(4);
+                return r;
+
+       }
+       return -1;
+}      
+
+static void on20_write_regr( PIA *pi, int cont, int regr, int val )
+
+{      int r;
+
+       r = (regr<<2) + 1 + cont;
+
+       op(1); vl(r); 
+       op(0); vl(val); 
+       op(0); vl(val);
+}
+
+static void on20_connect ( PIA *pi)
+
+{      pi->saved_r0 = r0();
+        pi->saved_r2 = r2();
+
+       w2(4);w0(0);w2(0xc);w2(4);w2(6);w2(4);w2(6);w2(4); 
+       if (pi->mode) { op(2); vl(8); op(2); vl(9); }
+              else   { op(2); vl(0); op(2); vl(8); }
+}
+
+static void on20_disconnect ( PIA *pi )
+
+{      w2(4);w0(7);w2(4);w2(0xc);w2(4);
+        w0(pi->saved_r0);
+        w2(pi->saved_r2);
+} 
+
+static void on20_read_block( PIA *pi, char * buf, int count )
+
+{      int     k, l, h; 
+
+       op(1); vl(1); op(0);
+
+       for (k=0;k<count;k++) 
+           if (pi->mode) {
+               w2(4); w2(0x26); buf[k] = r0();
+           } else {
+               w2(6); l = r1(); w2(4);
+               w2(6); h = r1(); w2(4);
+               buf[k] = j44(l,h);
+           }
+       w2(4);
+}
+
+static void on20_write_block(  PIA *pi, char * buf, int count )
+
+{      int     k;
+
+       op(1); vl(1); op(0);
+
+       for (k=0;k<count;k++) { w2(5); w0(buf[k]); w2(7); }
+       w2(4);
+}
+
+static void on20_log_adapter( PIA *pi, char * scratch, int verbose )
+
+{       char    *mode_string[2] = {"4-bit","8-bit"};
+
+        printk("%s: on20 %s, OnSpec 90c20 at 0x%x, ",
+                pi->device,ON20_VERSION,pi->port);
+        printk("mode %d (%s), delay %d\n",pi->mode,
+               mode_string[pi->mode],pi->delay);
+
+}
+
+static struct pi_protocol on20 = {
+       .owner          = THIS_MODULE,
+       .name           = "on20",
+       .max_mode       = 2,
+       .epp_first      = 2,
+       .default_delay  = 1,
+       .max_units      = 1,
+       .write_regr     = on20_write_regr,
+       .read_regr      = on20_read_regr,
+       .write_block    = on20_write_block,
+       .read_block     = on20_read_block,
+       .connect        = on20_connect,
+       .disconnect     = on20_disconnect,
+       .log_adapter    = on20_log_adapter,
+};
+
+static int __init on20_init(void)
+{
+       return paride_register(&on20);
+}
+
+static void __exit on20_exit(void)
+{
+       paride_unregister(&on20);
+}
+
+MODULE_LICENSE("GPL");
+module_init(on20_init)
+module_exit(on20_exit)
diff --git a/drivers/ata/pata_parport/on26.c b/drivers/ata/pata_parport/on26.c
new file mode 100644 (file)
index 0000000..35f1c48
--- /dev/null
@@ -0,0 +1,319 @@
+/* 
+        on26.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
+                              Under the terms of the GNU General Public License.
+
+        on26.c is a low-level protocol driver for the 
+        OnSpec 90c26 parallel to IDE adapter chip.
+
+*/
+
+/* Changes:
+
+        1.01    GRG 1998.05.06 init_proto, release_proto
+       1.02    GRG 1998.09.23 updates for the -E rev chip
+       1.03    GRG 1998.12.14 fix for slave drives
+       1.04    GRG 1998.12.20 yet another bug fix
+
+*/
+
+#define ON26_VERSION      "1.04"
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <asm/io.h>
+
+#include <linux/pata_parport.h>
+
+/* mode codes:  0  nybble reads, 8-bit writes
+                1  8-bit reads and writes
+                2  8-bit EPP mode
+               3  EPP-16
+               4  EPP-32
+*/
+
+#define j44(a,b)  (((a>>4)&0x0f)|(b&0xf0))
+
+#define P1     w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4);
+#define P2     w2(5);w2(7);w2(5);w2(4);
+
+/* cont = 0 - access the IDE register file 
+   cont = 1 - access the IDE command set 
+*/
+
+static int on26_read_regr( PIA *pi, int cont, int regr )
+
+{       int     a, b, r;
+
+       r = (regr<<2) + 1 + cont;
+
+        switch (pi->mode)  {
+
+        case 0: w0(1); P1; w0(r); P2; w0(0); P1; 
+               w2(6); a = r1(); w2(4);
+               w2(6); b = r1(); w2(4);
+               w2(6); w2(4); w2(6); w2(4);
+                return j44(a,b);
+
+        case 1: w0(1); P1; w0(r); P2; w0(0); P1;
+               w2(0x26); a = r0(); w2(4); w2(0x26); w2(4);
+                return a;
+
+       case 2:
+       case 3:
+        case 4: w3(1); w3(1); w2(5); w4(r); w2(4);
+               w3(0); w3(0); w2(0x24); a = r4(); w2(4);
+               w2(0x24); (void)r4(); w2(4);
+                return a;
+
+        }
+        return -1;
+}       
+
+static void on26_write_regr( PIA *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);\
+                w0(0x87);w0(0x78);w0(x);w2(4);w2(5);w2(4);w0(0xff);
+
+static void on26_connect ( PIA *pi )
+
+{       int    x;
+
+       pi->saved_r0 = r0();
+        pi->saved_r2 = r2();
+
+        CCP(0x20);
+       x = 8; if (pi->mode) x = 9;
+
+       w0(2); P1; w0(8); P2;
+       w0(2); P1; w0(x); P2;
+}
+
+static void on26_disconnect ( PIA *pi )
+
+{       if (pi->mode >= 2) { w3(4); w3(4); w3(4); w3(4); }
+                     else { w0(4); P1; w0(4); P1; }
+       CCP(0x30);
+        w0(pi->saved_r0);
+        w2(pi->saved_r2);
+} 
+
+#define        RESET_WAIT  200
+
+static int on26_test_port( PIA *pi)  /* hard reset */
+
+{       int     i, m, d, x=0, y=0;
+
+        pi->saved_r0 = r0();
+        pi->saved_r2 = r2();
+
+        d = pi->delay;
+        m = pi->mode;
+        pi->delay = 5;
+        pi->mode = 0;
+
+        w2(0xc);
+
+        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);
+
+        if (i == 0xb5f) {
+
+            w0(2); P1; w0(0);   P2;
+            w0(3); P1; w0(0);   P2;
+            w0(2); P1; w0(8);   P2; udelay(100);
+            w0(2); P1; w0(0xa); P2; udelay(100);
+            w0(2); P1; w0(8);   P2; udelay(1000);
+            
+            on26_write_regr(pi,0,6,0xa0);
+
+            for (i=0;i<RESET_WAIT;i++) {
+                on26_write_regr(pi,0,6,0xa0);
+                x = on26_read_regr(pi,0,7);
+                on26_write_regr(pi,0,6,0xb0);
+                y = on26_read_regr(pi,0,7);
+                if (!((x&0x80)||(y&0x80))) break;
+                mdelay(100);
+            }
+
+           if (i == RESET_WAIT) 
+               printk("on26: Device reset failed (%x,%x)\n",x,y);
+
+            w0(4); P1; w0(4); P1;
+        }
+
+        CCP(0x30);
+
+        pi->delay = d;
+        pi->mode = m;
+        w0(pi->saved_r0);
+        w2(pi->saved_r2);
+
+        return 5;
+}
+
+
+static void on26_read_block( PIA *pi, char * buf, int count )
+
+{       int     k, a, b;
+
+        switch (pi->mode) {
+
+        case 0: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x18); P2; w0(0); P1;
+               udelay(10);
+               for (k=0;k<count;k++) {
+                        w2(6); a = r1();
+                        w2(4); b = r1();
+                        buf[k] = j44(a,b);
+                }
+               w0(2); P1; w0(8); P2; 
+                break;
+
+        case 1: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x19); P2; w0(0); P1;
+               udelay(10);
+                for (k=0;k<count/2;k++) {
+                        w2(0x26); buf[2*k] = r0();  
+                       w2(0x24); buf[2*k+1] = r0();
+                }
+                w0(2); P1; w0(9); P2;
+                break;
+
+        case 2: w3(1); w3(1); w2(5); w4(1); w2(4);
+               w3(0); w3(0); w2(0x24);
+               udelay(10);
+                for (k=0;k<count;k++) buf[k] = r4();
+                w2(4);
+                break;
+
+        case 3: w3(1); w3(1); w2(5); w4(1); w2(4);
+                w3(0); w3(0); w2(0x24);
+                udelay(10);
+                for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
+                w2(4);
+                break;
+
+        case 4: w3(1); w3(1); w2(5); w4(1); w2(4);
+                w3(0); w3(0); w2(0x24);
+                udelay(10);
+                for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
+                w2(4);
+                break;
+
+        }
+}
+
+static void on26_write_block( PIA *pi, char * buf, int count )
+
+{       int    k;
+
+        switch (pi->mode) {
+
+        case 0: 
+        case 1: w0(1); P1; w0(1); P2; 
+               w0(2); P1; w0(0x18+pi->mode); P2; w0(0); P1;
+               udelay(10);
+               for (k=0;k<count/2;k++) {
+                        w2(5); w0(buf[2*k]); 
+                       w2(7); w0(buf[2*k+1]);
+                }
+                w2(5); w2(4);
+               w0(2); P1; w0(8+pi->mode); P2;
+                break;
+
+        case 2: w3(1); w3(1); w2(5); w4(1); w2(4);
+               w3(0); w3(0); w2(0xc5);
+               udelay(10);
+                for (k=0;k<count;k++) w4(buf[k]);
+               w2(0xc4);
+                break;
+
+        case 3: w3(1); w3(1); w2(5); w4(1); w2(4);
+                w3(0); w3(0); w2(0xc5);
+                udelay(10);
+                for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
+                w2(0xc4);
+                break;
+
+        case 4: w3(1); w3(1); w2(5); w4(1); w2(4);
+                w3(0); w3(0); w2(0xc5);
+                udelay(10);
+                for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
+                w2(0xc4);
+                break;
+
+        }
+
+}
+
+static void on26_log_adapter( PIA *pi, char * scratch, int verbose )
+
+{       char    *mode_string[5] = {"4-bit","8-bit","EPP-8",
+                                  "EPP-16","EPP-32"};
+
+        printk("%s: on26 %s, OnSpec 90c26 at 0x%x, ",
+                pi->device,ON26_VERSION,pi->port);
+        printk("mode %d (%s), delay %d\n",pi->mode,
+               mode_string[pi->mode],pi->delay);
+
+}
+
+static struct pi_protocol on26 = {
+       .owner          = THIS_MODULE,
+       .name           = "on26",
+       .max_mode       = 5,
+       .epp_first      = 2,
+       .default_delay  = 1,
+       .max_units      = 1,
+       .write_regr     = on26_write_regr,
+       .read_regr      = on26_read_regr,
+       .write_block    = on26_write_block,
+       .read_block     = on26_read_block,
+       .connect        = on26_connect,
+       .disconnect     = on26_disconnect,
+       .test_port      = on26_test_port,
+       .log_adapter    = on26_log_adapter,
+};
+
+static int __init on26_init(void)
+{
+       return paride_register(&on26);
+}
+
+static void __exit on26_exit(void)
+{
+       paride_unregister(&on26);
+}
+
+MODULE_LICENSE("GPL");
+module_init(on26_init)
+module_exit(on26_exit)
diff --git a/drivers/ata/pata_parport/pata_parport.c b/drivers/ata/pata_parport/pata_parport.c
new file mode 100644 (file)
index 0000000..9e8ad93
--- /dev/null
@@ -0,0 +1,759 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2023 Ondrej Zary
+ * based on paride.c by Grant R. Guenther <grant@torque.net>
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/parport.h>
+#include <linux/pata_parport.h>
+
+#define DRV_NAME "pata_parport"
+
+static DEFINE_IDR(parport_list);
+static DEFINE_IDR(protocols);
+static DEFINE_IDA(pata_parport_bus_dev_ids);
+static DEFINE_MUTEX(pi_mutex);
+
+static bool probe = true;
+module_param(probe, bool, 0644);
+MODULE_PARM_DESC(probe, "Enable automatic device probing (0=off, 1=on [default])");
+
+/*
+ * libata drivers cannot sleep so this driver claims parport before activating
+ * the ata host and keeps it claimed (and protocol connected) until the ata
+ * host is removed. Unfortunately, this means that you cannot use any chained
+ * devices (neither other pata_parport devices nor a printer).
+ */
+static void pi_connect(struct pi_adapter *pi)
+{
+       parport_claim_or_block(pi->pardev);
+       pi->proto->connect(pi);
+}
+
+static void pi_disconnect(struct pi_adapter *pi)
+{
+       pi->proto->disconnect(pi);
+       parport_release(pi->pardev);
+}
+
+static void pata_parport_dev_select(struct ata_port *ap, unsigned int device)
+{
+       struct pi_adapter *pi = ap->host->private_data;
+       u8 tmp;
+
+       if (device == 0)
+               tmp = ATA_DEVICE_OBS;
+       else
+               tmp = ATA_DEVICE_OBS | ATA_DEV1;
+
+       pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tmp);
+       ata_sff_pause(ap);
+}
+
+static bool pata_parport_devchk(struct ata_port *ap, unsigned int device)
+{
+       struct pi_adapter *pi = ap->host->private_data;
+       u8 nsect, lbal;
+
+       pata_parport_dev_select(ap, device);
+
+       pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0x55);
+       pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
+
+       pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0xaa);
+       pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0x55);
+
+       pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 055);
+       pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
+
+       nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
+       lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
+
+       return (nsect == 0x55) && (lbal == 0xaa);
+}
+
+static int pata_parport_bus_softreset(struct ata_port *ap, unsigned int devmask,
+                                     unsigned long deadline)
+{
+       struct pi_adapter *pi = ap->host->private_data;
+
+       /* software reset.  causes dev0 to be selected */
+       pi->proto->write_regr(pi, 1, 6, ap->ctl);
+       udelay(20);
+       pi->proto->write_regr(pi, 1, 6, ap->ctl | ATA_SRST);
+       udelay(20);
+       pi->proto->write_regr(pi, 1, 6, ap->ctl);
+       ap->last_ctl = ap->ctl;
+
+       /* wait the port to become ready */
+       return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
+}
+
+static int pata_parport_softreset(struct ata_link *link, unsigned int *classes,
+                                 unsigned long deadline)
+{
+       struct ata_port *ap = link->ap;
+       unsigned int devmask = 0;
+       int rc;
+       u8 err;
+
+       /* determine if device 0/1 are present */
+       if (pata_parport_devchk(ap, 0))
+               devmask |= (1 << 0);
+       if (pata_parport_devchk(ap, 1))
+               devmask |= (1 << 1);
+
+       /* select device 0 again */
+       pata_parport_dev_select(ap, 0);
+
+       /* issue bus reset */
+       rc = pata_parport_bus_softreset(ap, devmask, deadline);
+       if (rc && rc != -ENODEV) {
+               ata_link_err(link, "SRST failed (errno=%d)\n", rc);
+               return rc;
+       }
+
+       /* determine by signature whether we have ATA or ATAPI devices */
+       classes[0] = ata_sff_dev_classify(&link->device[0],
+                                         devmask & (1 << 0), &err);
+       if (err != 0x81)
+               classes[1] = ata_sff_dev_classify(&link->device[1],
+                                                 devmask & (1 << 1), &err);
+
+       return 0;
+}
+
+static u8 pata_parport_check_status(struct ata_port *ap)
+{
+       struct pi_adapter *pi = ap->host->private_data;
+
+       return pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
+}
+
+static u8 pata_parport_check_altstatus(struct ata_port *ap)
+{
+       struct pi_adapter *pi = ap->host->private_data;
+
+       return pi->proto->read_regr(pi, 1, 6);
+}
+
+static void pata_parport_tf_load(struct ata_port *ap,
+                                const struct ata_taskfile *tf)
+{
+       struct pi_adapter *pi = ap->host->private_data;
+
+       if (tf->ctl != ap->last_ctl) {
+               pi->proto->write_regr(pi, 1, 6, tf->ctl);
+               ap->last_ctl = tf->ctl;
+               ata_wait_idle(ap);
+       }
+
+       if (tf->flags & ATA_TFLAG_ISADDR) {
+               if (tf->flags & ATA_TFLAG_LBA48) {
+                       pi->proto->write_regr(pi, 0, ATA_REG_FEATURE,
+                                             tf->hob_feature);
+                       pi->proto->write_regr(pi, 0, ATA_REG_NSECT,
+                                             tf->hob_nsect);
+                       pi->proto->write_regr(pi, 0, ATA_REG_LBAL,
+                                             tf->hob_lbal);
+                       pi->proto->write_regr(pi, 0, ATA_REG_LBAM,
+                                             tf->hob_lbam);
+                       pi->proto->write_regr(pi, 0, ATA_REG_LBAH,
+                                             tf->hob_lbah);
+               }
+               pi->proto->write_regr(pi, 0, ATA_REG_FEATURE, tf->feature);
+               pi->proto->write_regr(pi, 0, ATA_REG_NSECT, tf->nsect);
+               pi->proto->write_regr(pi, 0, ATA_REG_LBAL, tf->lbal);
+               pi->proto->write_regr(pi, 0, ATA_REG_LBAM, tf->lbam);
+               pi->proto->write_regr(pi, 0, ATA_REG_LBAH, tf->lbah);
+       }
+
+       if (tf->flags & ATA_TFLAG_DEVICE)
+               pi->proto->write_regr(pi, 0, ATA_REG_DEVICE, tf->device);
+
+       ata_wait_idle(ap);
+}
+
+static void pata_parport_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+       struct pi_adapter *pi = ap->host->private_data;
+
+       tf->status = pi->proto->read_regr(pi, 0, ATA_REG_STATUS);
+       tf->error = pi->proto->read_regr(pi, 0, ATA_REG_ERR);
+       tf->nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
+       tf->lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
+       tf->lbam = pi->proto->read_regr(pi, 0, ATA_REG_LBAM);
+       tf->lbah = pi->proto->read_regr(pi, 0, ATA_REG_LBAH);
+       tf->device = pi->proto->read_regr(pi, 0, ATA_REG_DEVICE);
+
+       if (tf->flags & ATA_TFLAG_LBA48) {
+               pi->proto->write_regr(pi, 1, 6, tf->ctl | ATA_HOB);
+               tf->hob_feature = pi->proto->read_regr(pi, 0, ATA_REG_ERR);
+               tf->hob_nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
+               tf->hob_lbal = pi->proto->read_regr(pi, 0, ATA_REG_LBAL);
+               tf->hob_lbam = pi->proto->read_regr(pi, 0, ATA_REG_LBAM);
+               tf->hob_lbah = pi->proto->read_regr(pi, 0, ATA_REG_LBAH);
+               pi->proto->write_regr(pi, 1, 6, tf->ctl);
+               ap->last_ctl = tf->ctl;
+       }
+}
+
+static void pata_parport_exec_command(struct ata_port *ap,
+                                     const struct ata_taskfile *tf)
+{
+       struct pi_adapter *pi = ap->host->private_data;
+
+       pi->proto->write_regr(pi, 0, ATA_REG_CMD, tf->command);
+       ata_sff_pause(ap);
+}
+
+static unsigned int pata_parport_data_xfer(struct ata_queued_cmd *qc,
+                               unsigned char *buf, unsigned int buflen, int rw)
+{
+       struct ata_port *ap = qc->dev->link->ap;
+       struct pi_adapter *pi = ap->host->private_data;
+
+       if (rw == READ)
+               pi->proto->read_block(pi, buf, buflen);
+       else
+               pi->proto->write_block(pi, buf, buflen);
+
+       return buflen;
+}
+
+static void pata_parport_drain_fifo(struct ata_queued_cmd *qc)
+{
+       int count;
+       struct ata_port *ap;
+       struct pi_adapter *pi;
+       char junk[2];
+
+       /* We only need to flush incoming data when a command was running */
+       if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
+               return;
+
+       ap = qc->ap;
+       pi = ap->host->private_data;
+       /* Drain up to 64K of data before we give up this recovery method */
+       for (count = 0; (pata_parport_check_status(ap) & ATA_DRQ)
+                                               && count < 65536; count += 2) {
+               pi->proto->read_block(pi, junk, 2);
+       }
+
+       if (count)
+               ata_port_dbg(ap, "drained %d bytes to clear DRQ\n", count);
+}
+
+static struct ata_port_operations pata_parport_port_ops = {
+       .inherits               = &ata_sff_port_ops,
+
+       .softreset              = pata_parport_softreset,
+       .hardreset              = NULL,
+
+       .sff_dev_select         = pata_parport_dev_select,
+       .sff_check_status       = pata_parport_check_status,
+       .sff_check_altstatus    = pata_parport_check_altstatus,
+       .sff_tf_load            = pata_parport_tf_load,
+       .sff_tf_read            = pata_parport_tf_read,
+       .sff_exec_command       = pata_parport_exec_command,
+       .sff_data_xfer          = pata_parport_data_xfer,
+       .sff_drain_fifo         = pata_parport_drain_fifo,
+};
+
+static const struct ata_port_info pata_parport_port_info = {
+       .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_POLLING,
+       .pio_mask       = ATA_PIO0,
+       /* No DMA */
+       .port_ops       = &pata_parport_port_ops,
+};
+
+static void pi_release(struct pi_adapter *pi)
+{
+       parport_unregister_device(pi->pardev);
+       if (pi->proto->release_proto)
+               pi->proto->release_proto(pi);
+       module_put(pi->proto->owner);
+}
+
+static int default_test_proto(struct pi_adapter *pi, char *scratch)
+{
+       int j, k;
+       int e[2] = { 0, 0 };
+
+       pi->proto->connect(pi);
+
+       for (j = 0; j < 2; j++) {
+               pi->proto->write_regr(pi, 0, 6, 0xa0 + j * 0x10);
+               for (k = 0; k < 256; k++) {
+                       pi->proto->write_regr(pi, 0, 2, k ^ 0xaa);
+                       pi->proto->write_regr(pi, 0, 3, k ^ 0x55);
+                       if (pi->proto->read_regr(pi, 0, 2) != (k ^ 0xaa))
+                               e[j]++;
+               }
+       }
+       pi->proto->disconnect(pi);
+
+       dev_dbg(&pi->dev, "%s: port 0x%x, mode %d, test=(%d,%d)\n",
+               pi->proto->name, pi->port, pi->mode, e[0], e[1]);
+
+       return e[0] && e[1];    /* not here if both > 0 */
+}
+
+static int pi_test_proto(struct pi_adapter *pi, char *scratch)
+{
+       int res;
+
+       parport_claim_or_block(pi->pardev);
+       if (pi->proto->test_proto)
+               res = pi->proto->test_proto(pi, scratch, 1);
+       else
+               res = default_test_proto(pi, scratch);
+       parport_release(pi->pardev);
+
+       return res;
+}
+
+static bool pi_probe_mode(struct pi_adapter *pi, int max, char *scratch)
+{
+       int best, range;
+
+       if (pi->mode != -1) {
+               if (pi->mode >= max)
+                       return false;
+               range = 3;
+               if (pi->mode >= pi->proto->epp_first)
+                       range = 8;
+               if (range == 8 && pi->port % 8)
+                       return false;
+               return !pi_test_proto(pi, scratch);
+       }
+       best = -1;
+       for (pi->mode = 0; pi->mode < max; pi->mode++) {
+               range = 3;
+               if (pi->mode >= pi->proto->epp_first)
+                       range = 8;
+               if (range == 8 && pi->port % 8)
+                       break;
+               if (!pi_test_proto(pi, scratch))
+                       best = pi->mode;
+       }
+       pi->mode = best;
+       return best > -1;
+}
+
+static bool pi_probe_unit(struct pi_adapter *pi, int unit, char *scratch)
+{
+       int max, s, e;
+
+       s = unit;
+       e = s + 1;
+
+       if (s == -1) {
+               s = 0;
+               e = pi->proto->max_units;
+       }
+
+       if (pi->proto->test_port) {
+               parport_claim_or_block(pi->pardev);
+               max = pi->proto->test_port(pi);
+               parport_release(pi->pardev);
+       } else {
+               max = pi->proto->max_mode;
+       }
+
+       if (pi->proto->probe_unit) {
+               parport_claim_or_block(pi->pardev);
+               for (pi->unit = s; pi->unit < e; pi->unit++) {
+                       if (pi->proto->probe_unit(pi)) {
+                               parport_release(pi->pardev);
+                               return pi_probe_mode(pi, max, scratch);
+                       }
+               }
+               parport_release(pi->pardev);
+               return false;
+       }
+
+       return pi_probe_mode(pi, max, scratch);
+}
+
+static void pata_parport_dev_release(struct device *dev)
+{
+       struct pi_adapter *pi = container_of(dev, struct pi_adapter, dev);
+
+       kfree(pi);
+}
+
+static void pata_parport_bus_release(struct device *dev)
+{
+       /* nothing to do here but required to avoid warning on device removal */
+}
+
+static struct bus_type pata_parport_bus_type = {
+       .name = DRV_NAME,
+};
+
+static struct device pata_parport_bus = {
+       .init_name = DRV_NAME,
+       .release = pata_parport_bus_release,
+};
+
+static struct scsi_host_template pata_parport_sht = {
+       PATA_PARPORT_SHT("pata_parport")
+};
+
+struct pi_device_match {
+       struct parport *parport;
+       struct pi_protocol *proto;
+};
+
+static int pi_find_dev(struct device *dev, void *data)
+{
+       struct pi_adapter *pi = container_of(dev, struct pi_adapter, dev);
+       struct pi_device_match *match = data;
+
+       return pi->pardev->port == match->parport && pi->proto == match->proto;
+}
+
+static struct pi_adapter *pi_init_one(struct parport *parport,
+                       struct pi_protocol *pr, int mode, int unit, int delay)
+{
+       struct pardev_cb par_cb = { };
+       char scratch[512];
+       const struct ata_port_info *ppi[] = { &pata_parport_port_info };
+       struct ata_host *host;
+       struct pi_adapter *pi;
+       struct pi_device_match match = { .parport = parport, .proto = pr };
+
+       /*
+        * Abort if there's a device already registered on the same parport
+        * using the same protocol.
+        */
+       if (bus_for_each_dev(&pata_parport_bus_type, NULL, &match, pi_find_dev))
+               return NULL;
+
+       pi = kzalloc(sizeof(struct pi_adapter), GFP_KERNEL);
+       if (!pi)
+               return NULL;
+
+       /* set up pi->dev before pi_probe_unit() so it can use dev_printk() */
+       pi->dev.parent = &pata_parport_bus;
+       pi->dev.bus = &pata_parport_bus_type;
+       pi->dev.driver = &pr->driver;
+       pi->dev.release = pata_parport_dev_release;
+       pi->dev.id = ida_alloc(&pata_parport_bus_dev_ids, GFP_KERNEL);
+       if (pi->dev.id < 0)
+               return NULL; /* pata_parport_dev_release will do kfree(pi) */
+       dev_set_name(&pi->dev, "pata_parport.%u", pi->dev.id);
+       if (device_register(&pi->dev)) {
+               put_device(&pi->dev);
+               goto out_ida_free;
+       }
+
+       pi->proto = pr;
+
+       if (!try_module_get(pi->proto->owner))
+               goto out_unreg_dev;
+       if (pi->proto->init_proto && pi->proto->init_proto(pi) < 0)
+               goto out_module_put;
+
+       pi->delay = (delay == -1) ? pi->proto->default_delay : delay;
+       pi->mode = mode;
+       pi->port = parport->base;
+
+       par_cb.private = pi;
+       pi->pardev = parport_register_dev_model(parport, DRV_NAME, &par_cb,
+                                               pi->dev.id);
+       if (!pi->pardev)
+               goto out_module_put;
+
+       if (!pi_probe_unit(pi, unit, scratch)) {
+               dev_info(&pi->dev, "Adapter not found\n");
+               goto out_unreg_parport;
+       }
+
+       pi->proto->log_adapter(pi, scratch, 1);
+
+       host = ata_host_alloc_pinfo(&pi->pardev->dev, ppi, 1);
+       if (!host)
+               goto out_unreg_parport;
+       dev_set_drvdata(&pi->dev, host);
+       host->private_data = pi;
+
+       ata_port_desc(host->ports[0], "port %s", pi->pardev->port->name);
+       ata_port_desc(host->ports[0], "protocol %s", pi->proto->name);
+
+       pi_connect(pi);
+       if (ata_host_activate(host, 0, NULL, 0, &pata_parport_sht))
+               goto out_unreg_parport;
+
+       return pi;
+
+out_unreg_parport:
+       pi_disconnect(pi);
+       parport_unregister_device(pi->pardev);
+       if (pi->proto->release_proto)
+               pi->proto->release_proto(pi);
+out_module_put:
+       module_put(pi->proto->owner);
+out_unreg_dev:
+       device_unregister(&pi->dev);
+out_ida_free:
+       ida_free(&pata_parport_bus_dev_ids, pi->dev.id);
+       return NULL;
+}
+
+int pata_parport_register_driver(struct pi_protocol *pr)
+{
+       int error;
+       struct parport *parport;
+       int port_num;
+
+       pr->driver.bus = &pata_parport_bus_type;
+       pr->driver.name = pr->name;
+       error = driver_register(&pr->driver);
+       if (error)
+               return error;
+
+       mutex_lock(&pi_mutex);
+       error = idr_alloc(&protocols, pr, 0, 0, GFP_KERNEL);
+       if (error < 0) {
+               driver_unregister(&pr->driver);
+               mutex_unlock(&pi_mutex);
+               return error;
+       }
+
+       pr_info("pata_parport: protocol %s registered\n", pr->name);
+
+       if (probe) {
+               /* probe all parports using this protocol */
+               idr_for_each_entry(&parport_list, parport, port_num)
+                       pi_init_one(parport, pr, -1, 0, -1);
+       }
+       mutex_unlock(&pi_mutex);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(pata_parport_register_driver);
+
+void pata_parport_unregister_driver(struct pi_protocol *pr)
+{
+       struct pi_protocol *pr_iter;
+       int id = -1;
+
+       mutex_lock(&pi_mutex);
+       idr_for_each_entry(&protocols, pr_iter, id) {
+               if (pr_iter == pr)
+                       break;
+       }
+       idr_remove(&protocols, id);
+       mutex_unlock(&pi_mutex);
+       driver_unregister(&pr->driver);
+}
+EXPORT_SYMBOL_GPL(pata_parport_unregister_driver);
+
+static ssize_t new_device_store(struct bus_type *bus, const char *buf,
+                               size_t count)
+{
+       char port[12] = "auto";
+       char protocol[8] = "auto";
+       int mode = -1, unit = -1, delay = -1;
+       struct pi_protocol *pr, *pr_wanted;
+       struct device_driver *drv;
+       struct parport *parport;
+       int port_num, port_wanted, pr_num;
+       bool ok = false;
+
+       if (sscanf(buf, "%11s %7s %d %d %d",
+                       port, protocol, &mode, &unit, &delay) < 1)
+               return -EINVAL;
+
+       if (sscanf(port, "parport%u", &port_wanted) < 1) {
+               if (strcmp(port, "auto")) {
+                       pr_err("invalid port name %s\n", port);
+                       return -EINVAL;
+               }
+               port_wanted = -1;
+       }
+
+       drv = driver_find(protocol, &pata_parport_bus_type);
+       if (!drv) {
+               if (strcmp(protocol, "auto")) {
+                       pr_err("protocol %s not found\n", protocol);
+                       return -EINVAL;
+               }
+               pr_wanted = NULL;
+       } else {
+               pr_wanted = container_of(drv, struct pi_protocol, driver);
+       }
+
+       mutex_lock(&pi_mutex);
+       /* walk all parports */
+       idr_for_each_entry(&parport_list, parport, port_num) {
+               if (port_num == port_wanted || port_wanted == -1) {
+                       parport = parport_find_number(port_num);
+                       if (!parport) {
+                               pr_err("no such port %s\n", port);
+                               mutex_unlock(&pi_mutex);
+                               return -ENODEV;
+                       }
+                       /* walk all protocols */
+                       idr_for_each_entry(&protocols, pr, pr_num) {
+                               if (pr == pr_wanted || !pr_wanted)
+                                       if (pi_init_one(parport, pr, mode, unit,
+                                                       delay))
+                                               ok = true;
+                       }
+                       parport_put_port(parport);
+               }
+       }
+       mutex_unlock(&pi_mutex);
+       if (!ok)
+               return -ENODEV;
+
+       return count;
+}
+static BUS_ATTR_WO(new_device);
+
+static void pi_remove_one(struct device *dev)
+{
+       struct ata_host *host = dev_get_drvdata(dev);
+       struct pi_adapter *pi = host->private_data;
+
+       ata_host_detach(host);
+       pi_disconnect(pi);
+       pi_release(pi);
+       device_unregister(dev);
+       ida_free(&pata_parport_bus_dev_ids, dev->id);
+       /* pata_parport_dev_release will do kfree(pi) */
+}
+
+static ssize_t delete_device_store(struct bus_type *bus, const char *buf,
+                                  size_t count)
+{
+       struct device *dev;
+
+       mutex_lock(&pi_mutex);
+       dev = bus_find_device_by_name(bus, NULL, buf);
+       if (!dev) {
+               mutex_unlock(&pi_mutex);
+               return -ENODEV;
+       }
+
+       pi_remove_one(dev);
+       mutex_unlock(&pi_mutex);
+
+       return count;
+}
+static BUS_ATTR_WO(delete_device);
+
+static void pata_parport_attach(struct parport *port)
+{
+       struct pi_protocol *pr;
+       int pr_num, id;
+
+       mutex_lock(&pi_mutex);
+       id = idr_alloc(&parport_list, port, port->number, port->number,
+                      GFP_KERNEL);
+       if (id < 0) {
+               mutex_unlock(&pi_mutex);
+               return;
+       }
+
+       if (probe) {
+               /* probe this port using all protocols */
+               idr_for_each_entry(&protocols, pr, pr_num)
+                       pi_init_one(port, pr, -1, 0, -1);
+       }
+       mutex_unlock(&pi_mutex);
+}
+
+static int pi_remove_port(struct device *dev, void *p)
+{
+       struct ata_host *host = dev_get_drvdata(dev);
+       struct pi_adapter *pi = host->private_data;
+
+       if (pi->pardev->port == p)
+               pi_remove_one(dev);
+
+       return 0;
+}
+
+static void pata_parport_detach(struct parport *port)
+{
+       mutex_lock(&pi_mutex);
+       bus_for_each_dev(&pata_parport_bus_type, NULL, port, pi_remove_port);
+       idr_remove(&parport_list, port->number);
+       mutex_unlock(&pi_mutex);
+}
+
+static struct parport_driver pata_parport_driver = {
+       .name = DRV_NAME,
+       .match_port = pata_parport_attach,
+       .detach = pata_parport_detach,
+       .devmodel = true,
+};
+
+static __init int pata_parport_init(void)
+{
+       int error;
+
+       error = bus_register(&pata_parport_bus_type);
+       if (error) {
+               pr_err("failed to register pata_parport bus, error: %d\n", error);
+               return error;
+       }
+
+       error = device_register(&pata_parport_bus);
+       if (error) {
+               pr_err("failed to register pata_parport bus, error: %d\n", error);
+               goto out_unregister_bus;
+       }
+
+       error = bus_create_file(&pata_parport_bus_type, &bus_attr_new_device);
+       if (error) {
+               pr_err("unable to create sysfs file, error: %d\n", error);
+               goto out_unregister_dev;
+       }
+
+       error = bus_create_file(&pata_parport_bus_type, &bus_attr_delete_device);
+       if (error) {
+               pr_err("unable to create sysfs file, error: %d\n", error);
+               goto out_remove_new;
+       }
+
+       error = parport_register_driver(&pata_parport_driver);
+       if (error) {
+               pr_err("unable to register parport driver, error: %d\n", error);
+               goto out_remove_del;
+       }
+
+       return 0;
+
+out_remove_del:
+       bus_remove_file(&pata_parport_bus_type, &bus_attr_delete_device);
+out_remove_new:
+       bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
+out_unregister_dev:
+       device_unregister(&pata_parport_bus);
+out_unregister_bus:
+       bus_unregister(&pata_parport_bus_type);
+       return error;
+}
+
+static __exit void pata_parport_exit(void)
+{
+       parport_unregister_driver(&pata_parport_driver);
+       bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
+       bus_remove_file(&pata_parport_bus_type, &bus_attr_delete_device);
+       device_unregister(&pata_parport_bus);
+       bus_unregister(&pata_parport_bus_type);
+}
+
+MODULE_AUTHOR("Ondrej Zary");
+MODULE_DESCRIPTION("driver for parallel port ATA adapters");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("paride");
+
+module_init(pata_parport_init);
+module_exit(pata_parport_exit);
diff --git a/drivers/ata/pata_parport/ppc6lnx.c b/drivers/ata/pata_parport/ppc6lnx.c
new file mode 100644 (file)
index 0000000..5e5521d
--- /dev/null
@@ -0,0 +1,726 @@
+/*
+       ppc6lnx.c (c) 2001 Micro Solutions Inc.
+               Released under the terms of the GNU General Public license
+
+       ppc6lnx.c  is a par of the protocol driver for the Micro Solutions
+               "BACKPACK" parallel port IDE adapter
+               (Works on Series 6 drives)
+
+*/
+
+//***************************************************************************
+
+// PPC 6 Code in C sanitized for LINUX
+// Original x86 ASM by Ron, Converted to C by Clive
+
+//***************************************************************************
+
+
+#define port_stb                                       1
+#define port_afd                                       2
+#define cmd_stb                                                port_afd
+#define port_init                                      4
+#define data_stb                                       port_init
+#define port_sel                                       8
+#define port_int                                       16
+#define port_dir                                       0x20
+
+#define ECR_EPP        0x80
+#define ECR_BI 0x20
+
+//***************************************************************************
+
+//  60772 Commands
+
+#define ACCESS_REG                             0x00
+#define ACCESS_PORT                            0x40
+
+#define ACCESS_READ                            0x00
+#define ACCESS_WRITE                   0x20
+
+//  60772 Command Prefix
+
+#define CMD_PREFIX_SET         0xe0            // Special command that modifies the next command's operation
+#define CMD_PREFIX_RESET       0xc0            // Resets current cmd modifier reg bits
+ #define PREFIX_IO16                   0x01            // perform 16-bit wide I/O
+ #define PREFIX_FASTWR         0x04            // enable PPC mode fast-write
+ #define PREFIX_BLK                            0x08            // enable block transfer mode
+
+// 60772 Registers
+
+#define REG_STATUS                             0x00            // status register
+ #define STATUS_IRQA                   0x01            // Peripheral IRQA line
+ #define STATUS_EEPROM_DO      0x40            // Serial EEPROM data bit
+#define REG_VERSION                            0x01            // PPC version register (read)
+#define REG_HWCFG                                      0x02            // Hardware Config register
+#define REG_RAMSIZE                            0x03            // Size of RAM Buffer
+ #define RAMSIZE_128K                  0x02
+#define REG_EEPROM                             0x06            // EEPROM control register
+ #define EEPROM_SK                             0x01            // eeprom SK bit
+ #define EEPROM_DI                             0x02            // eeprom DI bit
+ #define EEPROM_CS                             0x04            // eeprom CS bit
+ #define EEPROM_EN                             0x08            // eeprom output enable
+#define REG_BLKSIZE                            0x08            // Block transfer len (24 bit)
+
+//***************************************************************************
+
+typedef struct ppc_storage {
+       u16     lpt_addr;                               // LPT base address
+       u8      ppc_id;
+       u8      mode;                                           // operating mode
+                                       // 0 = PPC Uni SW
+                                       // 1 = PPC Uni FW
+                                       // 2 = PPC Bi SW
+                                       // 3 = PPC Bi FW
+                                       // 4 = EPP Byte
+                                       // 5 = EPP Word
+                                       // 6 = EPP Dword
+       u8      ppc_flags;
+       u8      org_data;                               // original LPT data port contents
+       u8      org_ctrl;                               // original LPT control port contents
+       u8      cur_ctrl;                               // current control port contents
+} Interface;
+
+//***************************************************************************
+
+// ppc_flags
+
+#define fifo_wait                                      0x10
+
+//***************************************************************************
+
+// DONT CHANGE THESE LEST YOU BREAK EVERYTHING - BIT FIELD DEPENDENCIES
+
+#define PPCMODE_UNI_SW         0
+#define PPCMODE_UNI_FW         1
+#define PPCMODE_BI_SW                  2
+#define PPCMODE_BI_FW                  3
+#define PPCMODE_EPP_BYTE       4
+#define PPCMODE_EPP_WORD       5
+#define PPCMODE_EPP_DWORD      6
+
+//***************************************************************************
+
+static int ppc6_select(Interface *ppc);
+static void ppc6_deselect(Interface *ppc);
+static void ppc6_send_cmd(Interface *ppc, u8 cmd);
+static void ppc6_wr_data_byte(Interface *ppc, u8 data);
+static u8 ppc6_rd_data_byte(Interface *ppc);
+static u8 ppc6_rd_port(Interface *ppc, u8 port);
+static void ppc6_wr_port(Interface *ppc, u8 port, u8 data);
+static void ppc6_rd_data_blk(Interface *ppc, u8 *data, long count);
+static void ppc6_wait_for_fifo(Interface *ppc);
+static void ppc6_wr_data_blk(Interface *ppc, u8 *data, long count);
+static void ppc6_rd_port16_blk(Interface *ppc, u8 port, u8 *data, long length);
+static void ppc6_wr_port16_blk(Interface *ppc, u8 port, u8 *data, long length);
+static void ppc6_wr_extout(Interface *ppc, u8 regdata);
+static int ppc6_open(Interface *ppc);
+static void ppc6_close(Interface *ppc);
+
+//***************************************************************************
+
+static int ppc6_select(Interface *ppc)
+{
+       u8 i, j, k;
+
+       i = inb(ppc->lpt_addr + 1);
+
+       if (i & 1)
+               outb(i, ppc->lpt_addr + 1);
+
+       ppc->org_data = inb(ppc->lpt_addr);
+
+       ppc->org_ctrl = inb(ppc->lpt_addr + 2) & 0x5F; // readback ctrl
+
+       ppc->cur_ctrl = ppc->org_ctrl;
+
+       ppc->cur_ctrl |= port_sel;
+
+       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+       if (ppc->org_data == 'b')
+               outb('x', ppc->lpt_addr);
+
+       outb('b', ppc->lpt_addr);
+       outb('p', ppc->lpt_addr);
+       outb(ppc->ppc_id, ppc->lpt_addr);
+       outb(~ppc->ppc_id,ppc->lpt_addr);
+
+       ppc->cur_ctrl &= ~port_sel;
+
+       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+       ppc->cur_ctrl = (ppc->cur_ctrl & port_int) | port_init;
+
+       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+       i = ppc->mode & 0x0C;
+
+       if (i == 0)
+               i = (ppc->mode & 2) | 1;
+
+       outb(i, ppc->lpt_addr);
+
+       ppc->cur_ctrl |= port_sel;
+
+       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+       // DELAY
+
+       ppc->cur_ctrl |= port_afd;
+
+       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+       j = ((i & 0x08) << 4) | ((i & 0x07) << 3);
+
+       k = inb(ppc->lpt_addr + 1) & 0xB8;
+
+       if (j == k)
+       {
+               ppc->cur_ctrl &= ~port_afd;
+
+               outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+               k = (inb(ppc->lpt_addr + 1) & 0xB8) ^ 0xB8;
+
+               if (j == k)
+               {
+                       if (i & 4)      // EPP
+                               ppc->cur_ctrl &= ~(port_sel | port_init);
+                       else                            // PPC/ECP
+                               ppc->cur_ctrl &= ~port_sel;
+
+                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                       return(1);
+               }
+       }
+
+       outb(ppc->org_ctrl, ppc->lpt_addr + 2);
+
+       outb(ppc->org_data, ppc->lpt_addr);
+
+       return(0); // FAIL
+}
+
+//***************************************************************************
+
+static void ppc6_deselect(Interface *ppc)
+{
+       if (ppc->mode & 4)      // EPP
+               ppc->cur_ctrl |= port_init;
+       else                                                            // PPC/ECP
+               ppc->cur_ctrl |= port_sel;
+
+       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+       outb(ppc->org_data, ppc->lpt_addr);
+
+       outb((ppc->org_ctrl | port_sel), ppc->lpt_addr + 2);
+
+       outb(ppc->org_ctrl, ppc->lpt_addr + 2);
+}
+
+//***************************************************************************
+
+static void ppc6_send_cmd(Interface *ppc, u8 cmd)
+{
+       switch(ppc->mode)
+       {
+               case PPCMODE_UNI_SW :
+               case PPCMODE_UNI_FW :
+               case PPCMODE_BI_SW :
+               case PPCMODE_BI_FW :
+               {
+                       outb(cmd, ppc->lpt_addr);
+
+                       ppc->cur_ctrl ^= cmd_stb;
+
+                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                       break;
+               }
+
+               case PPCMODE_EPP_BYTE :
+               case PPCMODE_EPP_WORD :
+               case PPCMODE_EPP_DWORD :
+               {
+                       outb(cmd, ppc->lpt_addr + 3);
+
+                       break;
+               }
+       }
+}
+
+//***************************************************************************
+
+static void ppc6_wr_data_byte(Interface *ppc, u8 data)
+{
+       switch(ppc->mode)
+       {
+               case PPCMODE_UNI_SW :
+               case PPCMODE_UNI_FW :
+               case PPCMODE_BI_SW :
+               case PPCMODE_BI_FW :
+               {
+                       outb(data, ppc->lpt_addr);
+
+                       ppc->cur_ctrl ^= data_stb;
+
+                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                       break;
+               }
+
+               case PPCMODE_EPP_BYTE :
+               case PPCMODE_EPP_WORD :
+               case PPCMODE_EPP_DWORD :
+               {
+                       outb(data, ppc->lpt_addr + 4);
+
+                       break;
+               }
+       }
+}
+
+//***************************************************************************
+
+static u8 ppc6_rd_data_byte(Interface *ppc)
+{
+       u8 data = 0;
+
+       switch(ppc->mode)
+       {
+               case PPCMODE_UNI_SW :
+               case PPCMODE_UNI_FW :
+               {
+                       ppc->cur_ctrl = (ppc->cur_ctrl & ~port_stb) ^ data_stb;
+
+                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                       // DELAY
+
+                       data = inb(ppc->lpt_addr + 1);
+
+                       data = ((data & 0x80) >> 1) | ((data & 0x38) >> 3);
+
+                       ppc->cur_ctrl |= port_stb;
+
+                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                       // DELAY
+
+                       data |= inb(ppc->lpt_addr + 1) & 0xB8;
+
+                       break;
+               }
+
+               case PPCMODE_BI_SW :
+               case PPCMODE_BI_FW :
+               {
+                       ppc->cur_ctrl |= port_dir;
+
+                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                       ppc->cur_ctrl = (ppc->cur_ctrl | port_stb) ^ data_stb;
+
+                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                       data = inb(ppc->lpt_addr);
+
+                       ppc->cur_ctrl &= ~port_stb;
+
+                       outb(ppc->cur_ctrl,ppc->lpt_addr + 2);
+
+                       ppc->cur_ctrl &= ~port_dir;
+
+                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                       break;
+               }
+
+               case PPCMODE_EPP_BYTE :
+               case PPCMODE_EPP_WORD :
+               case PPCMODE_EPP_DWORD :
+               {
+                       outb((ppc->cur_ctrl | port_dir),ppc->lpt_addr + 2);
+
+                       data = inb(ppc->lpt_addr + 4);
+
+                       outb(ppc->cur_ctrl,ppc->lpt_addr + 2);
+
+                       break;
+               }
+       }
+
+       return(data);
+}
+
+//***************************************************************************
+
+static u8 ppc6_rd_port(Interface *ppc, u8 port)
+{
+       ppc6_send_cmd(ppc,(u8)(port | ACCESS_PORT | ACCESS_READ));
+
+       return(ppc6_rd_data_byte(ppc));
+}
+
+//***************************************************************************
+
+static void ppc6_wr_port(Interface *ppc, u8 port, u8 data)
+{
+       ppc6_send_cmd(ppc,(u8)(port | ACCESS_PORT | ACCESS_WRITE));
+
+       ppc6_wr_data_byte(ppc, data);
+}
+
+//***************************************************************************
+
+static void ppc6_rd_data_blk(Interface *ppc, u8 *data, long count)
+{
+       switch(ppc->mode)
+       {
+               case PPCMODE_UNI_SW :
+               case PPCMODE_UNI_FW :
+               {
+                       while(count)
+                       {
+                               u8 d;
+
+                               ppc->cur_ctrl = (ppc->cur_ctrl & ~port_stb) ^ data_stb;
+
+                               outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                               // DELAY
+
+                               d = inb(ppc->lpt_addr + 1);
+
+                               d = ((d & 0x80) >> 1) | ((d & 0x38) >> 3);
+
+                               ppc->cur_ctrl |= port_stb;
+
+                               outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                               // DELAY
+
+                               d |= inb(ppc->lpt_addr + 1) & 0xB8;
+
+                               *data++ = d;
+                               count--;
+                       }
+
+                       break;
+               }
+
+               case PPCMODE_BI_SW :
+               case PPCMODE_BI_FW :
+               {
+                       ppc->cur_ctrl |= port_dir;
+
+                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                       ppc->cur_ctrl |= port_stb;
+
+                       while(count)
+                       {
+                               ppc->cur_ctrl ^= data_stb;
+
+                               outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                               *data++ = inb(ppc->lpt_addr);
+                               count--;
+                       }
+
+                       ppc->cur_ctrl &= ~port_stb;
+
+                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                       ppc->cur_ctrl &= ~port_dir;
+
+                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                       break;
+               }
+
+               case PPCMODE_EPP_BYTE :
+               {
+                       outb((ppc->cur_ctrl | port_dir), ppc->lpt_addr + 2);
+
+                       // DELAY
+
+                       while(count)
+                       {
+                               *data++ = inb(ppc->lpt_addr + 4);
+                               count--;
+                       }
+
+                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                       break;
+               }
+
+               case PPCMODE_EPP_WORD :
+               {
+                       outb((ppc->cur_ctrl | port_dir), ppc->lpt_addr + 2);
+
+                       // DELAY
+
+                       while(count > 1)
+                       {
+                               *((u16 *)data) = inw(ppc->lpt_addr + 4);
+                               data  += 2;
+                               count -= 2;
+                       }
+
+                       while(count)
+                       {
+                               *data++ = inb(ppc->lpt_addr + 4);
+                               count--;
+                       }
+
+                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                       break;
+               }
+
+               case PPCMODE_EPP_DWORD :
+               {
+                       outb((ppc->cur_ctrl | port_dir),ppc->lpt_addr + 2);
+
+                       // DELAY
+
+                       while(count > 3)
+                       {
+                               *((u32 *)data) = inl(ppc->lpt_addr + 4);
+                               data  += 4;
+                               count -= 4;
+                       }
+
+                       while(count)
+                       {
+                               *data++ = inb(ppc->lpt_addr + 4);
+                               count--;
+                       }
+
+                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                       break;
+               }
+       }
+
+}
+
+//***************************************************************************
+
+static void ppc6_wait_for_fifo(Interface *ppc)
+{
+       int i;
+
+       if (ppc->ppc_flags & fifo_wait)
+       {
+               for(i=0; i<20; i++)
+                       inb(ppc->lpt_addr + 1);
+       }
+}
+
+//***************************************************************************
+
+static void ppc6_wr_data_blk(Interface *ppc, u8 *data, long count)
+{
+       switch(ppc->mode)
+       {
+               case PPCMODE_UNI_SW :
+               case PPCMODE_BI_SW :
+               {
+                       while(count--)
+                       {
+                               outb(*data++, ppc->lpt_addr);
+
+                               ppc->cur_ctrl ^= data_stb;
+
+                               outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+                       }
+
+                       break;
+               }
+
+               case PPCMODE_UNI_FW :
+               case PPCMODE_BI_FW :
+               {
+                       u8 this, last;
+
+                       ppc6_send_cmd(ppc,(CMD_PREFIX_SET | PREFIX_FASTWR));
+
+                       ppc->cur_ctrl |= port_stb;
+
+                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                       last = *data;
+
+                       outb(last, ppc->lpt_addr);
+
+                       while(count)
+                       {
+                               this = *data++;
+                               count--;
+
+                               if (this == last)
+                               {
+                                       ppc->cur_ctrl ^= data_stb;
+
+                                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+                               }
+                               else
+                               {
+                                       outb(this, ppc->lpt_addr);
+
+                                       last = this;
+                               }
+                       }
+
+                       ppc->cur_ctrl &= ~port_stb;
+
+                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+                       ppc6_send_cmd(ppc,(CMD_PREFIX_RESET | PREFIX_FASTWR));
+
+                       break;
+               }
+
+               case PPCMODE_EPP_BYTE :
+               {
+                       while(count)
+                       {
+                               outb(*data++,ppc->lpt_addr + 4);
+                               count--;
+                       }
+
+                       ppc6_wait_for_fifo(ppc);
+
+                       break;
+               }
+
+               case PPCMODE_EPP_WORD :
+               {
+                       while(count > 1)
+                       {
+                               outw(*((u16 *)data),ppc->lpt_addr + 4);
+                               data  += 2;
+                               count -= 2;
+                       }
+
+                       while(count)
+                       {
+                               outb(*data++,ppc->lpt_addr + 4);
+                               count--;
+                       }
+
+                       ppc6_wait_for_fifo(ppc);
+
+                       break;
+               }
+
+               case PPCMODE_EPP_DWORD :
+               {
+                       while(count > 3)
+                       {
+                               outl(*((u32 *)data),ppc->lpt_addr + 4);
+                               data  += 4;
+                               count -= 4;
+                       }
+
+                       while(count)
+                       {
+                               outb(*data++,ppc->lpt_addr + 4);
+                               count--;
+                       }
+
+                       ppc6_wait_for_fifo(ppc);
+
+                       break;
+               }
+       }
+}
+
+//***************************************************************************
+
+static void ppc6_rd_port16_blk(Interface *ppc, u8 port, u8 *data, long length)
+{
+       length = length << 1;
+
+       ppc6_send_cmd(ppc, (REG_BLKSIZE | ACCESS_REG | ACCESS_WRITE));
+       ppc6_wr_data_byte(ppc,(u8)length);
+       ppc6_wr_data_byte(ppc,(u8)(length >> 8));
+       ppc6_wr_data_byte(ppc,0);
+
+       ppc6_send_cmd(ppc, (CMD_PREFIX_SET | PREFIX_IO16 | PREFIX_BLK));
+
+       ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_READ));
+
+       ppc6_rd_data_blk(ppc, data, length);
+
+       ppc6_send_cmd(ppc, (CMD_PREFIX_RESET | PREFIX_IO16 | PREFIX_BLK));
+}
+
+//***************************************************************************
+
+static void ppc6_wr_port16_blk(Interface *ppc, u8 port, u8 *data, long length)
+{
+       length = length << 1;
+
+       ppc6_send_cmd(ppc, (REG_BLKSIZE | ACCESS_REG | ACCESS_WRITE));
+       ppc6_wr_data_byte(ppc,(u8)length);
+       ppc6_wr_data_byte(ppc,(u8)(length >> 8));
+       ppc6_wr_data_byte(ppc,0);
+
+       ppc6_send_cmd(ppc, (CMD_PREFIX_SET | PREFIX_IO16 | PREFIX_BLK));
+
+       ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_WRITE));
+
+       ppc6_wr_data_blk(ppc, data, length);
+
+       ppc6_send_cmd(ppc, (CMD_PREFIX_RESET | PREFIX_IO16 | PREFIX_BLK));
+}
+
+//***************************************************************************
+
+static void ppc6_wr_extout(Interface *ppc, u8 regdata)
+{
+       ppc6_send_cmd(ppc,(REG_VERSION | ACCESS_REG | ACCESS_WRITE));
+
+       ppc6_wr_data_byte(ppc, (u8)((regdata & 0x03) << 6));
+}
+
+//***************************************************************************
+
+static int ppc6_open(Interface *ppc)
+{
+       int ret;
+
+       ret = ppc6_select(ppc);
+
+       if (ret == 0)
+               return(ret);
+
+       ppc->ppc_flags &= ~fifo_wait;
+
+       ppc6_send_cmd(ppc, (ACCESS_REG | ACCESS_WRITE | REG_RAMSIZE));
+       ppc6_wr_data_byte(ppc, RAMSIZE_128K);
+
+       ppc6_send_cmd(ppc, (ACCESS_REG | ACCESS_READ | REG_VERSION));
+
+       if ((ppc6_rd_data_byte(ppc) & 0x3F) == 0x0C)
+               ppc->ppc_flags |= fifo_wait;
+
+       return(ret);
+}
+
+//***************************************************************************
+
+static void ppc6_close(Interface *ppc)
+{
+       ppc6_deselect(ppc);
+}
+
+//***************************************************************************
+
index 71c9c6e3c07ae7f72adf999546df3fb00c4424f2..89d5cca82f006145dd73393f2f7a94f9a5307081 100644 (file)
@@ -103,8 +103,6 @@ config GDROM
          Most users will want to say "Y" here.
          You can also build this as a module which will be called gdrom.
 
-source "drivers/block/paride/Kconfig"
-
 source "drivers/block/mtip32xx/Kconfig"
 
 source "drivers/block/zram/Kconfig"
diff --git a/drivers/block/paride/Kconfig b/drivers/block/paride/Kconfig
deleted file mode 100644 (file)
index 19310be..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# PARIDE configuration
-
-comment "Parallel IDE protocol modules"
-       depends on PATA_PARPORT
-
-config PARIDE_ATEN
-       tristate "ATEN EH-100 protocol"
-       depends on PATA_PARPORT
-       help
-         This option enables support for the ATEN EH-100 parallel port IDE
-         protocol. This protocol is used in some inexpensive low performance
-         parallel port kits made in Hong Kong. If you chose to build PARIDE
-         support into your kernel, you may answer Y here to build in the
-         protocol driver, otherwise you should answer M to build it as a
-         loadable module. The module will be called aten. You must also
-         have a high-level driver for the type of device that you want to
-         support.
-
-config PARIDE_BPCK
-       tristate "MicroSolutions backpack (Series 5) protocol"
-       depends on PATA_PARPORT
-       help
-         This option enables support for the Micro Solutions BACKPACK
-         parallel port Series 5 IDE protocol.  (Most BACKPACK drives made
-         before 1999 were Series 5) Series 5 drives will NOT always have the
-         Series noted on the bottom of the drive. Series 6 drivers will.
-
-         In other words, if your BACKPACK drive doesn't say "Series 6" on the
-         bottom, enable this option.
-
-         If you chose to build PARIDE support into your kernel, you may
-         answer Y here to build in the protocol driver, otherwise you should
-         answer M to build it as a loadable module.  The module will be
-         called bpck.  You must also have a high-level driver for the type
-         of device that you want to support.
-
-config PARIDE_BPCK6
-       tristate "MicroSolutions backpack (Series 6) protocol"
-       depends on (PATA_PARPORT) && !64BIT
-       help
-         This option enables support for the Micro Solutions BACKPACK
-         parallel port Series 6 IDE protocol.  (Most BACKPACK drives made
-         after 1999 were Series 6) Series 6 drives will have the Series noted
-         on the bottom of the drive.  Series 5 drivers don't always have it
-         noted.
-
-         In other words, if your BACKPACK drive says "Series 6" on the
-         bottom, enable this option.
-
-         If you chose to build PARIDE support into your kernel, you may
-         answer Y here to build in the protocol driver, otherwise you should
-         answer M to build it as a loadable module.  The module will be
-         called bpck6.  You must also have a high-level driver for the type
-         of device that you want to support.
-
-config PARIDE_COMM
-       tristate "DataStor Commuter protocol"
-       depends on PATA_PARPORT
-       help
-         This option enables support for the Commuter parallel port IDE
-         protocol from DataStor. If you chose to build PARIDE support
-         into your kernel, you may answer Y here to build in the protocol
-         driver, otherwise you should answer M to build it as a loadable
-         module. The module will be called comm. You must also have
-         a high-level driver for the type of device that you want to support.
-
-config PARIDE_DSTR
-       tristate "DataStor EP-2000 protocol"
-       depends on PATA_PARPORT
-       help
-         This option enables support for the EP-2000 parallel port IDE
-         protocol from DataStor. If you chose to build PARIDE support
-         into your kernel, you may answer Y here to build in the protocol
-         driver, otherwise you should answer M to build it as a loadable
-         module. The module will be called dstr. You must also have
-         a high-level driver for the type of device that you want to support.
-
-config PARIDE_FIT2
-       tristate "FIT TD-2000 protocol"
-       depends on PATA_PARPORT
-       help
-         This option enables support for the TD-2000 parallel port IDE
-         protocol from Fidelity International Technology. This is a simple
-         (low speed) adapter that is used in some portable hard drives. If
-         you chose to build PARIDE support into your kernel, you may answer Y
-         here to build in the protocol driver, otherwise you should answer M
-         to build it as a loadable module. The module will be called ktti.
-         You must also have a high-level driver for the type of device that
-         you want to support.
-
-config PARIDE_FIT3
-       tristate "FIT TD-3000 protocol"
-       depends on PATA_PARPORT
-       help
-         This option enables support for the TD-3000 parallel port IDE
-         protocol from Fidelity International Technology. This protocol is
-         used in newer models of their portable disk, CD-ROM and PD/CD
-         devices. If you chose to build PARIDE support into your kernel, you
-         may answer Y here to build in the protocol driver, otherwise you
-         should answer M to build it as a loadable module. The module will be
-         called fit3. You must also have a high-level driver for the type
-         of device that you want to support.
-
-config PARIDE_EPAT
-       tristate "Shuttle EPAT/EPEZ protocol"
-       depends on PATA_PARPORT
-       help
-         This option enables support for the EPAT parallel port IDE protocol.
-         EPAT is a parallel port IDE adapter manufactured by Shuttle
-         Technology and widely used in devices from major vendors such as
-         Hewlett-Packard, SyQuest, Imation and Avatar. If you chose to build
-         PARIDE support into your kernel, you may answer Y here to build in
-         the protocol driver, otherwise you should answer M to build it as a
-         loadable module. The module will be called epat. You must also
-         have a high-level driver for the type of device that you want to
-         support.
-
-config PARIDE_EPATC8
-       bool "Support c7/c8 chips"
-       depends on PARIDE_EPAT
-       help
-         This option enables support for the newer Shuttle EP1284 (aka c7 and
-         c8) chip. You need this if you are using any recent Imation SuperDisk
-         (LS-120) drive.
-
-config PARIDE_EPIA
-       tristate "Shuttle EPIA protocol"
-       depends on PATA_PARPORT
-       help
-         This option enables support for the (obsolete) EPIA parallel port
-         IDE protocol from Shuttle Technology. This adapter can still be
-         found in some no-name kits. If you chose to build PARIDE support
-         into your kernel, you may answer Y here to build in the protocol
-         driver, otherwise you should answer M to build it as a loadable
-         module. The module will be called epia. You must also have a
-         high-level driver for the type of device that you want to support.
-
-config PARIDE_FRIQ
-       tristate "Freecom IQ ASIC-2 protocol"
-       depends on PATA_PARPORT
-       help
-         This option enables support for version 2 of the Freecom IQ parallel
-         port IDE adapter.  This adapter is used by the Maxell Superdisk
-         drive.  If you chose to build PARIDE support into your kernel, you
-         may answer Y here to build in the protocol driver, otherwise you
-         should answer M to build it as a loadable module. The module will be
-         called friq. You must also have a high-level driver for the type
-         of device that you want to support.
-
-config PARIDE_FRPW
-       tristate "FreeCom power protocol"
-       depends on PATA_PARPORT
-       help
-         This option enables support for the Freecom power parallel port IDE
-         protocol. If you chose to build PARIDE support into your kernel, you
-         may answer Y here to build in the protocol driver, otherwise you
-         should answer M to build it as a loadable module. The module will be
-         called frpw. You must also have a high-level driver for the type
-         of device that you want to support.
-
-config PARIDE_KBIC
-       tristate "KingByte KBIC-951A/971A protocols"
-       depends on PATA_PARPORT
-       help
-         This option enables support for the KBIC-951A and KBIC-971A parallel
-         port IDE protocols from KingByte Information Corp. KingByte's
-         adapters appear in many no-name portable disk and CD-ROM products,
-         especially in Europe. If you chose to build PARIDE support into your
-         kernel, you may answer Y here to build in the protocol driver,
-         otherwise you should answer M to build it as a loadable module. The
-         module will be called kbic. You must also have a high-level driver
-         for the type of device that you want to support.
-
-config PARIDE_KTTI
-       tristate "KT PHd protocol"
-       depends on PATA_PARPORT
-       help
-         This option enables support for the "PHd" parallel port IDE protocol
-         from KT Technology. This is a simple (low speed) adapter that is
-         used in some 2.5" portable hard drives. If you chose to build PARIDE
-         support into your kernel, you may answer Y here to build in the
-         protocol driver, otherwise you should answer M to build it as a
-         loadable module. The module will be called ktti. You must also
-         have a high-level driver for the type of device that you want to
-         support.
-
-config PARIDE_ON20
-       tristate "OnSpec 90c20 protocol"
-       depends on PATA_PARPORT
-       help
-         This option enables support for the (obsolete) 90c20 parallel port
-         IDE protocol from OnSpec (often marketed under the ValuStore brand
-         name). If you chose to build PARIDE support into your kernel, you
-         may answer Y here to build in the protocol driver, otherwise you
-         should answer M to build it as a loadable module. The module will
-         be called on20. You must also have a high-level driver for the
-         type of device that you want to support.
-
-config PARIDE_ON26
-       tristate "OnSpec 90c26 protocol"
-       depends on PATA_PARPORT
-       help
-         This option enables support for the 90c26 parallel port IDE protocol
-         from OnSpec Electronics (often marketed under the ValuStore brand
-         name). If you chose to build PARIDE support into your kernel, you
-         may answer Y here to build in the protocol driver, otherwise you
-         should answer M to build it as a loadable module. The module will be
-         called on26. You must also have a high-level driver for the type
-         of device that you want to support.
-
-#
diff --git a/drivers/block/paride/Makefile b/drivers/block/paride/Makefile
deleted file mode 100644 (file)
index cdf54a2..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for Parallel port IDE device drivers.
-#
-# 7 October 2000, Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
-# Rewritten to use lists instead of if-statements.
-#
-
-obj-$(CONFIG_PARIDE_ATEN)      += aten.o
-obj-$(CONFIG_PARIDE_BPCK)      += bpck.o
-obj-$(CONFIG_PARIDE_COMM)      += comm.o
-obj-$(CONFIG_PARIDE_DSTR)      += dstr.o
-obj-$(CONFIG_PARIDE_KBIC)      += kbic.o
-obj-$(CONFIG_PARIDE_EPAT)      += epat.o
-obj-$(CONFIG_PARIDE_EPIA)      += epia.o
-obj-$(CONFIG_PARIDE_FRPW)      += frpw.o
-obj-$(CONFIG_PARIDE_FRIQ)      += friq.o
-obj-$(CONFIG_PARIDE_FIT2)      += fit2.o
-obj-$(CONFIG_PARIDE_FIT3)      += fit3.o
-obj-$(CONFIG_PARIDE_ON20)      += on20.o
-obj-$(CONFIG_PARIDE_ON26)      += on26.o
-obj-$(CONFIG_PARIDE_KTTI)      += ktti.o
-obj-$(CONFIG_PARIDE_BPCK6)     += bpck6.o
diff --git a/drivers/block/paride/aten.c b/drivers/block/paride/aten.c
deleted file mode 100644 (file)
index b66508b..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/* 
-        aten.c  (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                            Under the terms of the GNU General Public License.
-
-       aten.c is a low-level protocol driver for the ATEN EH-100
-       parallel port adapter.  The EH-100 supports 4-bit and 8-bit
-        modes only.  There is also an EH-132 which supports EPP mode
-        transfers.  The EH-132 is not yet supported.
-
-*/
-
-/* Changes:
-
-       1.01    GRG 1998.05.05  init_proto, release_proto
-
-*/
-
-#define ATEN_VERSION      "1.01"
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/wait.h>
-#include <linux/types.h>
-#include <asm/io.h>
-
-#include <linux/pata_parport.h>
-
-#define j44(a,b)                ((((a>>4)&0x0f)|(b&0xf0))^0x88)
-
-/* cont = 0 - access the IDE register file 
-   cont = 1 - access the IDE command set 
-*/
-
-static int  cont_map[2] = { 0x08, 0x20 };
-
-static void  aten_write_regr( PIA *pi, int cont, int regr, int val)
-
-{      int r;
-
-       r = regr + cont_map[cont] + 0x80;
-
-       w0(r); w2(0xe); w2(6); w0(val); w2(7); w2(6); w2(0xc);
-}
-
-static int aten_read_regr( PIA *pi, int cont, int regr )
-
-{      int  a, b, r;
-
-        r = regr + cont_map[cont] + 0x40;
-
-       switch (pi->mode) {
-
-        case 0: w0(r); w2(0xe); w2(6); 
-               w2(7); w2(6); w2(0);
-               a = r1(); w0(0x10); b = r1(); w2(0xc);
-               return j44(a,b);
-
-        case 1: r |= 0x10;
-               w0(r); w2(0xe); w2(6); w0(0xff); 
-               w2(0x27); w2(0x26); w2(0x20);
-               a = r0();
-               w2(0x26); w2(0xc);
-               return a;
-       }
-       return -1;
-}
-
-static void aten_read_block( PIA *pi, char * buf, int count )
-
-{      int  k, a, b, c, d;
-
-       switch (pi->mode) {
-
-       case 0: w0(0x48); w2(0xe); w2(6);
-               for (k=0;k<count/2;k++) {
-                       w2(7); w2(6); w2(2);
-                       a = r1(); w0(0x58); b = r1();
-                       w2(0); d = r1(); w0(0x48); c = r1();
-                       buf[2*k] = j44(c,d);
-                       buf[2*k+1] = j44(a,b);
-               }
-               w2(0xc);
-               break;
-
-       case 1: w0(0x58); w2(0xe); w2(6);
-               for (k=0;k<count/2;k++) {
-                       w2(0x27); w2(0x26); w2(0x22);
-                       a = r0(); w2(0x20); b = r0();
-                       buf[2*k] = b; buf[2*k+1] = a;
-               }
-               w2(0x26); w2(0xc);
-               break;
-       }
-}
-
-static void aten_write_block( PIA *pi, char * buf, int count )
-
-{      int k;
-
-       w0(0x88); w2(0xe); w2(6);
-       for (k=0;k<count/2;k++) {
-               w0(buf[2*k+1]); w2(0xe); w2(6);
-               w0(buf[2*k]); w2(7); w2(6);
-       }
-       w2(0xc);
-}
-
-static void aten_connect ( PIA *pi  )
-
-{       pi->saved_r0 = r0();
-        pi->saved_r2 = r2();
-       w2(0xc);        
-}
-
-static void aten_disconnect ( PIA *pi )
-
-{       w0(pi->saved_r0);
-        w2(pi->saved_r2);
-} 
-
-static void aten_log_adapter( PIA *pi, char * scratch, int verbose )
-
-{       char    *mode_string[2] = {"4-bit","8-bit"};
-
-        printk("%s: aten %s, ATEN EH-100 at 0x%x, ",
-                pi->device,ATEN_VERSION,pi->port);
-        printk("mode %d (%s), delay %d\n",pi->mode,
-               mode_string[pi->mode],pi->delay);
-
-}
-
-static struct pi_protocol aten = {
-       .owner          = THIS_MODULE,
-       .name           = "aten",
-       .max_mode       = 2,
-       .epp_first      = 2,
-       .default_delay  = 1,
-       .max_units      = 1,
-       .write_regr     = aten_write_regr,
-       .read_regr      = aten_read_regr,
-       .write_block    = aten_write_block,
-       .read_block     = aten_read_block,
-       .connect        = aten_connect,
-       .disconnect     = aten_disconnect,
-       .log_adapter    = aten_log_adapter,
-};
-
-static int __init aten_init(void)
-{
-       return paride_register(&aten);
-}
-
-static void __exit aten_exit(void)
-{
-       paride_unregister( &aten );
-}
-
-MODULE_LICENSE("GPL");
-module_init(aten_init)
-module_exit(aten_exit)
diff --git a/drivers/block/paride/bpck.c b/drivers/block/paride/bpck.c
deleted file mode 100644 (file)
index 5fb3cf9..0000000
+++ /dev/null
@@ -1,477 +0,0 @@
-/* 
-       bpck.c  (c) 1996-8  Grant R. Guenther <grant@torque.net>
-                           Under the terms of the GNU General Public License.
-
-       bpck.c is a low-level protocol driver for the MicroSolutions 
-       "backpack" parallel port IDE adapter.  
-
-*/
-
-/* Changes:
-
-       1.01    GRG 1998.05.05 init_proto, release_proto, pi->delay 
-       1.02    GRG 1998.08.15 default pi->delay returned to 4
-
-*/
-
-#define        BPCK_VERSION    "1.02" 
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <asm/io.h>
-
-#include <linux/pata_parport.h>
-
-#undef r2
-#undef w2
-#undef PC
-
-#define PC                     pi->private
-#define r2()                   (PC=(in_p(2) & 0xff))
-#define w2(byte)               {out_p(2,byte); PC = byte;}
-#define t2(pat)                {PC ^= pat; out_p(2,PC);}
-#define e2()                   {PC &= 0xfe; out_p(2,PC);}
-#define o2()                   {PC |= 1; out_p(2,PC);}
-
-#define j44(l,h)     (((l>>3)&0x7)|((l>>4)&0x8)|((h<<1)&0x70)|(h&0x80))
-
-/* cont = 0 - access the IDE register file 
-   cont = 1 - access the IDE command set 
-   cont = 2 - use internal bpck register addressing
-*/
-
-static int  cont_map[3] = { 0x40, 0x48, 0 };
-
-static int bpck_read_regr( PIA *pi, int cont, int regr )
-
-{       int r, l, h;
-
-       r = regr + cont_map[cont];
-
-       switch (pi->mode) {
-
-       case 0: w0(r & 0xf); w0(r); t2(2); t2(4);
-               l = r1();
-               t2(4);
-               h = r1();
-               return j44(l,h);
-
-       case 1: w0(r & 0xf); w0(r); t2(2);
-               e2(); t2(0x20);
-               t2(4); h = r0();
-               t2(1); t2(0x20);
-               return h;
-
-       case 2:
-       case 3:
-       case 4: w0(r); w2(9); w2(0); w2(0x20);
-               h = r4();
-               w2(0);
-               return h;
-
-       }
-       return -1;
-}      
-
-static void bpck_write_regr( PIA *pi, int cont, int regr, int val )
-
-{      int     r;
-
-        r = regr + cont_map[cont];
-
-       switch (pi->mode) {
-
-       case 0:
-       case 1: w0(r);
-               t2(2);
-               w0(val);
-               o2(); t2(4); t2(1);
-               break;
-
-       case 2:
-       case 3:
-       case 4: w0(r); w2(9); w2(0);
-               w0(val); w2(1); w2(3); w2(0);
-               break;
-
-       }
-}
-
-/* These macros access the bpck registers in native addressing */
-
-#define WR(r,v)                bpck_write_regr(pi,2,r,v)
-#define RR(r)          (bpck_read_regr(pi,2,r))
-
-static void bpck_write_block( PIA *pi, char * buf, int count )
-
-{      int i;
-
-       switch (pi->mode) {
-
-       case 0: WR(4,0x40);
-               w0(0x40); t2(2); t2(1);
-               for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
-               WR(4,0);
-               break;
-
-       case 1: WR(4,0x50);
-                w0(0x40); t2(2); t2(1);
-                for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
-                WR(4,0x10);
-               break;
-
-       case 2: WR(4,0x48);
-               w0(0x40); w2(9); w2(0); w2(1);
-               for (i=0;i<count;i++) w4(buf[i]);
-               w2(0);
-               WR(4,8);
-               break;
-
-        case 3: WR(4,0x48);
-                w0(0x40); w2(9); w2(0); w2(1);
-                for (i=0;i<count/2;i++) w4w(((u16 *)buf)[i]);
-                w2(0);
-                WR(4,8);
-                break;
-        case 4: WR(4,0x48);
-                w0(0x40); w2(9); w2(0); w2(1);
-                for (i=0;i<count/4;i++) w4l(((u32 *)buf)[i]);
-                w2(0);
-                WR(4,8);
-                break;
-       }
-}
-
-static void bpck_read_block( PIA *pi, char * buf, int count )
-
-{      int i, l, h;
-
-       switch (pi->mode) {
-
-       case 0: WR(4,0x40);
-               w0(0x40); t2(2);
-               for (i=0;i<count;i++) {
-                   t2(4); l = r1();
-                   t2(4); h = r1();
-                   buf[i] = j44(l,h);
-               }
-               WR(4,0);
-               break;
-
-       case 1: WR(4,0x50);
-               w0(0x40); t2(2); t2(0x20);
-               for(i=0;i<count;i++) { t2(4); buf[i] = r0(); }
-               t2(1); t2(0x20);
-               WR(4,0x10);
-               break;
-
-       case 2: WR(4,0x48);
-               w0(0x40); w2(9); w2(0); w2(0x20);
-               for (i=0;i<count;i++) buf[i] = r4();
-               w2(0);
-               WR(4,8);
-               break;
-
-        case 3: WR(4,0x48);
-                w0(0x40); w2(9); w2(0); w2(0x20);
-                for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
-                w2(0);
-                WR(4,8);
-                break;
-
-        case 4: WR(4,0x48);
-                w0(0x40); w2(9); w2(0); w2(0x20);
-                for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
-                w2(0);
-                WR(4,8);
-                break;
-
-       }
-}
-
-static int bpck_probe_unit ( PIA *pi )
-
-{      int o1, o0, f7, id;
-       int t, s;
-
-       id = pi->unit;
-       s = 0;
-       w2(4); w2(0xe); r2(); t2(2); 
-       o1 = r1()&0xf8;
-       o0 = r0();
-       w0(255-id); w2(4); w0(id);
-       t2(8); t2(8); t2(8);
-       t2(2); t = r1()&0xf8;
-       f7 = ((id % 8) == 7);
-       if ((f7) || (t != o1)) { t2(2); s = r1()&0xf8; }
-       if ((t == o1) && ((!f7) || (s == o1)))  {
-               w2(0x4c); w0(o0);
-               return 0;       
-       }
-       t2(8); w0(0); t2(2); w2(0x4c); w0(o0);
-       return 1;
-}
-       
-static void bpck_connect ( PIA *pi  )
-
-{       pi->saved_r0 = r0();
-       w0(0xff-pi->unit); w2(4); w0(pi->unit);
-       t2(8); t2(8); t2(8); 
-       t2(2); t2(2);
-       
-       switch (pi->mode) {
-
-       case 0: t2(8); WR(4,0);
-               break;
-
-       case 1: t2(8); WR(4,0x10);
-               break;
-
-       case 2:
-        case 3:
-       case 4: w2(0); WR(4,8);
-               break;
-
-       }
-
-       WR(5,8);
-
-       if (pi->devtype == PI_PCD) {
-               WR(0x46,0x10);          /* fiddle with ESS logic ??? */
-               WR(0x4c,0x38);
-               WR(0x4d,0x88);
-               WR(0x46,0xa0);
-               WR(0x41,0);
-               WR(0x4e,8);
-               }
-}
-
-static void bpck_disconnect ( PIA *pi )
-
-{      w0(0); 
-       if (pi->mode >= 2) { w2(9); w2(0); } else t2(2);
-       w2(0x4c); w0(pi->saved_r0);
-} 
-
-static void bpck_force_spp ( PIA *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);
-
-        w2(0); 
-        w0(4); w2(9); w2(0); 
-        w0(0); w2(1); w2(3); w2(0);     
-        w0(0); w2(9); w2(0);
-        w2(0x4c); w0(pi->saved_r0);
-}
-
-#define TEST_LEN  16
-
-static int bpck_test_proto( PIA *pi, char * scratch, int verbose )
-
-{      int i, e, l, h, om;
-       char buf[TEST_LEN];
-
-       bpck_force_spp(pi);
-
-       switch (pi->mode) {
-
-       case 0: bpck_connect(pi);
-               WR(0x13,0x7f);
-               w0(0x13); t2(2);
-               for(i=0;i<TEST_LEN;i++) {
-                    t2(4); l = r1();
-                    t2(4); h = r1();
-                    buf[i] = j44(l,h);
-               }
-               bpck_disconnect(pi);
-               break;
-
-        case 1: bpck_connect(pi);
-               WR(0x13,0x7f);
-                w0(0x13); t2(2); t2(0x20);
-                for(i=0;i<TEST_LEN;i++) { t2(4); buf[i] = r0(); }
-                t2(1); t2(0x20);
-               bpck_disconnect(pi);
-               break;
-
-       case 2:
-       case 3:
-       case 4: om = pi->mode;
-               pi->mode = 0;
-               bpck_connect(pi);
-               WR(7,3);
-               WR(4,8);
-               bpck_disconnect(pi);
-
-               pi->mode = om;
-               bpck_connect(pi);
-               w0(0x13); w2(9); w2(1); w0(0); w2(3); w2(0); w2(0xe0);
-
-               switch (pi->mode) {
-                 case 2: for (i=0;i<TEST_LEN;i++) buf[i] = r4();
-                         break;
-                 case 3: for (i=0;i<TEST_LEN/2;i++) ((u16 *)buf)[i] = r4w();
-                          break;
-                 case 4: for (i=0;i<TEST_LEN/4;i++) ((u32 *)buf)[i] = r4l();
-                          break;
-               }
-
-               w2(0);
-               WR(7,0);
-               bpck_disconnect(pi);
-
-               break;
-
-       }
-
-       if (verbose) {
-           printk("%s: bpck: 0x%x unit %d mode %d: ",
-                  pi->device,pi->port,pi->unit,pi->mode);
-           for (i=0;i<TEST_LEN;i++) printk("%3d",buf[i]);
-           printk("\n");
-       }
-
-       e = 0;
-       for (i=0;i<TEST_LEN;i++) if (buf[i] != (i+1)) e++;
-       return e;
-}
-
-static void bpck_read_eeprom ( PIA *pi, char * buf )
-
-{       int i, j, k, p, v, f, om, od;
-
-       bpck_force_spp(pi);
-
-       om = pi->mode;  od = pi->delay;
-       pi->mode = 0; pi->delay = 6;
-
-       bpck_connect(pi);
-       
-       WR(4,0);
-       for (i=0;i<64;i++) {
-           WR(6,8);  
-           WR(6,0xc);
-           p = 0x100;
-           for (k=0;k<9;k++) {
-               f = (((i + 0x180) & p) != 0) * 2;
-               WR(6,f+0xc); 
-               WR(6,f+0xd); 
-               WR(6,f+0xc);
-               p = (p >> 1);
-           }
-           for (j=0;j<2;j++) {
-               v = 0;
-               for (k=0;k<8;k++) {
-                   WR(6,0xc); 
-                   WR(6,0xd); 
-                   WR(6,0xc); 
-                   f = RR(0);
-                   v = 2*v + (f == 0x84);
-               }
-               buf[2*i+1-j] = v;
-           }
-       }
-       WR(6,8);
-       WR(6,0);
-       WR(5,8);
-
-       bpck_disconnect(pi);
-
-        if (om >= 2) {
-                bpck_connect(pi);
-                WR(7,3);
-                WR(4,8);
-                bpck_disconnect(pi);
-        }
-
-       pi->mode = om; pi->delay = od;
-}
-
-static int bpck_test_port ( PIA *pi )  /* check for 8-bit port */
-
-{      int     i, r, m;
-
-       w2(0x2c); i = r0(); w0(255-i); r = r0(); w0(i);
-       m = -1;
-       if (r == i) m = 2;
-       if (r == (255-i)) m = 0;
-
-       w2(0xc); i = r0(); w0(255-i); r = r0(); w0(i);
-       if (r != (255-i)) m = -1;
-       
-       if (m == 0) { w2(6); w2(0xc); r = r0(); w0(0xaa); w0(r); w0(0xaa); }
-       if (m == 2) { w2(0x26); w2(0xc); }
-
-       if (m == -1) return 0;
-       return 5;
-}
-
-static void bpck_log_adapter( PIA *pi, char * scratch, int verbose )
-
-{      char    *mode_string[5] = { "4-bit","8-bit","EPP-8",
-                                   "EPP-16","EPP-32" };
-
-#ifdef DUMP_EEPROM
-       int i;
-#endif
-
-       bpck_read_eeprom(pi,scratch);
-
-#ifdef DUMP_EEPROM
-       if (verbose) {
-          for(i=0;i<128;i++)
-               if ((scratch[i] < ' ') || (scratch[i] > '~'))
-                   scratch[i] = '.';
-          printk("%s: bpck EEPROM: %64.64s\n",pi->device,scratch);
-          printk("%s:              %64.64s\n",pi->device,&scratch[64]);
-       }
-#endif
-
-       printk("%s: bpck %s, backpack %8.8s unit %d",
-               pi->device,BPCK_VERSION,&scratch[110],pi->unit);
-       printk(" at 0x%x, mode %d (%s), delay %d\n",pi->port,
-               pi->mode,mode_string[pi->mode],pi->delay);
-}
-
-static struct pi_protocol bpck = {
-       .owner          = THIS_MODULE,
-       .name           = "bpck",
-       .max_mode       = 5,
-       .epp_first      = 2,
-       .default_delay  = 4,
-       .max_units      = 255,
-       .write_regr     = bpck_write_regr,
-       .read_regr      = bpck_read_regr,
-       .write_block    = bpck_write_block,
-       .read_block     = bpck_read_block,
-       .connect        = bpck_connect,
-       .disconnect     = bpck_disconnect,
-       .test_port      = bpck_test_port,
-       .probe_unit     = bpck_probe_unit,
-       .test_proto     = bpck_test_proto,
-       .log_adapter    = bpck_log_adapter,
-};
-
-static int __init bpck_init(void)
-{
-       return paride_register(&bpck);
-}
-
-static void __exit bpck_exit(void)
-{
-       paride_unregister(&bpck);
-}
-
-MODULE_LICENSE("GPL");
-module_init(bpck_init)
-module_exit(bpck_exit)
diff --git a/drivers/block/paride/bpck6.c b/drivers/block/paride/bpck6.c
deleted file mode 100644 (file)
index d897e2a..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
-       backpack.c (c) 2001 Micro Solutions Inc.
-               Released under the terms of the GNU General Public license
-
-       backpack.c is a low-level protocol driver for the Micro Solutions
-               "BACKPACK" parallel port IDE adapter
-               (Works on Series 6 drives)
-
-       Written by: Ken Hahn     (linux-dev@micro-solutions.com)
-                   Clive Turvey (linux-dev@micro-solutions.com)
-
-*/
-
-/*
-   This is Ken's linux wrapper for the PPC library
-   Version 1.0.0 is the backpack driver for which source is not available
-   Version 2.0.0 is the first to have source released 
-   Version 2.0.1 is the "Cox-ified" source code 
-   Version 2.0.2 - fixed version string usage, and made ppc functions static 
-*/
-
-
-#define BACKPACK_VERSION "2.0.2"
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <asm/io.h>
-#include <linux/parport.h>
-
-#include "ppc6lnx.c"
-#include <linux/pata_parport.h>
-
-/* PARAMETERS */
-static bool verbose; /* set this to 1 to see debugging messages and whatnot */
-
-#define PPCSTRUCT(pi) ((Interface *)(pi->private))
-
-/****************************************************************/
-/*
- ATAPI CDROM DRIVE REGISTERS
-*/
-#define ATAPI_DATA       0      /* data port                  */
-#define ATAPI_ERROR      1      /* error register (read)      */
-#define ATAPI_FEATURES   1      /* feature register (write)   */
-#define ATAPI_INT_REASON 2      /* interrupt reason register  */
-#define ATAPI_COUNT_LOW  4      /* byte count register (low)  */
-#define ATAPI_COUNT_HIGH 5      /* byte count register (high) */
-#define ATAPI_DRIVE_SEL  6      /* drive select register      */
-#define ATAPI_STATUS     7      /* status port (read)         */
-#define ATAPI_COMMAND    7      /* command port (write)       */
-#define ATAPI_ALT_STATUS 0x0e /* alternate status reg (read) */
-#define ATAPI_DEVICE_CONTROL 0x0e /* device control (write)   */
-/****************************************************************/
-
-static int bpck6_read_regr(PIA *pi, int cont, int reg)
-{
-       unsigned int out;
-
-       /* check for bad settings */
-       if (reg<0 || reg>7 || cont<0 || cont>2)
-       {
-               return(-1);
-       }
-       out=ppc6_rd_port(PPCSTRUCT(pi),cont?reg|8:reg);
-       return(out);
-}
-
-static void bpck6_write_regr(PIA *pi, int cont, int reg, int val)
-{
-       /* check for bad settings */
-       if (reg>=0 && reg<=7 && cont>=0 && cont<=1)
-       {
-               ppc6_wr_port(PPCSTRUCT(pi),cont?reg|8:reg,(u8)val);
-       }
-}
-
-static void bpck6_write_block( PIA *pi, char * buf, int len )
-{
-       ppc6_wr_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(u32)len>>1); 
-}
-
-static void bpck6_read_block( PIA *pi, char * buf, int len )
-{
-       ppc6_rd_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(u32)len>>1);
-}
-
-static void bpck6_connect ( PIA *pi  )
-{
-       if(verbose)
-       {
-               printk(KERN_DEBUG "connect\n");
-       }
-
-       if(pi->mode >=2)
-       {
-               PPCSTRUCT(pi)->mode=4+pi->mode-2;       
-       }
-       else if(pi->mode==1)
-       {
-               PPCSTRUCT(pi)->mode=3;  
-       }
-       else
-       {
-               PPCSTRUCT(pi)->mode=1;          
-       }
-
-       ppc6_open(PPCSTRUCT(pi));  
-       ppc6_wr_extout(PPCSTRUCT(pi),0x3);
-}
-
-static void bpck6_disconnect ( PIA *pi )
-{
-       if(verbose)
-       {
-               printk("disconnect\n");
-       }
-       ppc6_wr_extout(PPCSTRUCT(pi),0x0);
-       ppc6_close(PPCSTRUCT(pi));
-}
-
-static int bpck6_test_port ( PIA *pi )   /* check for 8-bit port */
-{
-       if(verbose)
-       {
-               printk(KERN_DEBUG "PARPORT indicates modes=%x for lp=0x%lx\n",
-                               ((struct pardevice*)(pi->pardev))->port->modes,
-                       ((struct pardevice *)(pi->pardev))->port->base); 
-       }
-
-       /*copy over duplicate stuff.. initialize state info*/
-       PPCSTRUCT(pi)->ppc_id=pi->unit;
-       PPCSTRUCT(pi)->lpt_addr=pi->port;
-
-       /* look at the parport device to see if what modes we can use */
-       if(((struct pardevice *)(pi->pardev))->port->modes & 
-               (PARPORT_MODE_EPP)
-          )
-       {
-               return 5; /* Can do EPP*/
-       }
-       else if(((struct pardevice *)(pi->pardev))->port->modes & 
-                       (PARPORT_MODE_TRISTATE)
-               )
-       {
-               return 2;
-       }
-       else /*Just flat SPP*/
-       {
-               return 1;
-       }
-}
-
-static int bpck6_probe_unit ( PIA *pi )
-{
-       int out;
-
-       if(verbose)
-       {
-               printk(KERN_DEBUG "PROBE UNIT %x on port:%x\n",pi->unit,pi->port);
-       }
-
-       /*SET PPC UNIT NUMBER*/
-       PPCSTRUCT(pi)->ppc_id=pi->unit;
-
-       /*LOWER DOWN TO UNIDIRECTIONAL*/
-       PPCSTRUCT(pi)->mode=1;          
-
-       out=ppc6_open(PPCSTRUCT(pi));
-
-       if(verbose)
-       {
-               printk(KERN_DEBUG "ppc_open returned %2x\n",out);
-       }
-
-       if(out)
-       {
-               ppc6_close(PPCSTRUCT(pi));
-               if(verbose)
-               {
-                       printk(KERN_DEBUG "leaving probe\n");
-               }
-               return(1);
-       }
-       else
-       {
-               if(verbose)
-               {
-                       printk(KERN_DEBUG "Failed open\n");
-               }
-               return(0);
-       }
-}
-
-static void bpck6_log_adapter( PIA *pi, char * scratch, int verbose )
-{
-       char *mode_string[5]=
-               {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
-
-       printk("%s: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n",pi->device);
-       printk("%s: Copyright 2001 by Micro Solutions, Inc., DeKalb IL.\n",pi->device);
-       printk("%s: BACKPACK %s, Micro Solutions BACKPACK Drive at 0x%x\n",
-               pi->device,BACKPACK_VERSION,pi->port);
-       printk("%s: Unit: %d Mode:%d (%s) Delay %d\n",pi->device,
-               pi->unit,pi->mode,mode_string[pi->mode],pi->delay);
-}
-
-static int bpck6_init_proto(PIA *pi)
-{
-       Interface *p = kzalloc(sizeof(Interface), GFP_KERNEL);
-
-       if (p) {
-               pi->private = (unsigned long)p;
-               return 0;
-       }
-
-       printk(KERN_ERR "%s: ERROR COULDN'T ALLOCATE MEMORY\n", pi->device); 
-       return -1;
-}
-
-static void bpck6_release_proto(PIA *pi)
-{
-       kfree((void *)(pi->private)); 
-}
-
-static struct pi_protocol bpck6 = {
-       .owner          = THIS_MODULE,
-       .name           = "bpck6",
-       .max_mode       = 5,
-       .epp_first      = 2, /* 2-5 use epp (need 8 ports) */
-       .max_units      = 255,
-       .write_regr     = bpck6_write_regr,
-       .read_regr      = bpck6_read_regr,
-       .write_block    = bpck6_write_block,
-       .read_block     = bpck6_read_block,
-       .connect        = bpck6_connect,
-       .disconnect     = bpck6_disconnect,
-       .test_port      = bpck6_test_port,
-       .probe_unit     = bpck6_probe_unit,
-       .log_adapter    = bpck6_log_adapter,
-       .init_proto     = bpck6_init_proto,
-       .release_proto  = bpck6_release_proto,
-};
-
-static int __init bpck6_init(void)
-{
-       printk(KERN_INFO "bpck6: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n");
-       printk(KERN_INFO "bpck6: Copyright 2001 by Micro Solutions, Inc., DeKalb IL. USA\n");
-       if(verbose)
-               printk(KERN_DEBUG "bpck6: verbose debug enabled.\n");
-       return paride_register(&bpck6);
-}
-
-static void __exit bpck6_exit(void)
-{
-       paride_unregister(&bpck6);
-}
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Micro Solutions Inc.");
-MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE");
-module_param(verbose, bool, 0644);
-module_init(bpck6_init)
-module_exit(bpck6_exit)
diff --git a/drivers/block/paride/comm.c b/drivers/block/paride/comm.c
deleted file mode 100644 (file)
index 1775e7e..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-/* 
-        comm.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                              Under the terms of the GNU General Public License.
-
-       comm.c is a low-level protocol driver for some older models
-       of the DataStor "Commuter" parallel to IDE adapter.  Some of
-       the parallel port devices marketed by Arista currently
-       use this adapter.
-*/
-
-/* Changes:
-
-       1.01    GRG 1998.05.05  init_proto, release_proto
-
-*/
-
-#define COMM_VERSION      "1.01"
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <asm/io.h>
-
-#include <linux/pata_parport.h>
-
-/* mode codes:  0  nybble reads, 8-bit writes
-                1  8-bit reads and writes
-                2  8-bit EPP mode
-*/
-
-#define j44(a,b)       (((a>>3)&0x0f)|((b<<1)&0xf0))
-
-#define P1     w2(5);w2(0xd);w2(0xd);w2(5);w2(4);
-#define P2     w2(5);w2(7);w2(7);w2(5);w2(4);
-
-/* cont = 0 - access the IDE register file 
-   cont = 1 - access the IDE command set 
-*/
-
-static int  cont_map[2] = { 0x08, 0x10 };
-
-static int comm_read_regr( PIA *pi, int cont, int regr )
-
-{       int     l, h, r;
-
-        r = regr + cont_map[cont];
-
-        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 1: w0(r+0x20); P1; 
-               w0(0); w2(0x26); h = r0(); w2(4);
-                return h;
-
-       case 2:
-       case 3:
-        case 4: w3(r+0x20); (void)r1();
-               w2(0x24); h = r4(); w2(4);
-                return h;
-
-        }
-        return -1;
-}       
-
-static void comm_write_regr( PIA *pi, int cont, int regr, int val )
-
-{       int  r;
-
-        r = regr + cont_map[cont];
-
-        switch (pi->mode)  {
-
-        case 0:
-        case 1: w0(r); P1; w0(val); P2;
-               break;
-
-       case 2:
-       case 3:
-        case 4: w3(r); (void)r1(); w4(val);
-                break;
-        }
-}
-
-static void comm_connect ( PIA *pi  )
-
-{       pi->saved_r0 = r0();
-        pi->saved_r2 = r2();
-        w2(4); w0(0xff); w2(6);
-        w2(4); w0(0xaa); w2(6);
-        w2(4); w0(0x00); w2(6);
-        w2(4); w0(0x87); w2(6);
-        w2(4); w0(0xe0); w2(0xc); w2(0xc); w2(4);
-}
-
-static void comm_disconnect ( PIA *pi )
-
-{       w2(0); w2(0); w2(0); w2(4); 
-       w0(pi->saved_r0);
-        w2(pi->saved_r2);
-} 
-
-static void comm_read_block( PIA *pi, char * buf, int count )
-
-{       int     i, l, h;
-
-        switch (pi->mode) {
-        
-        case 0: w0(0x48); P1;
-                for(i=0;i<count;i++) {
-                        w0(0); w2(6); l = r1();
-                        w0(0x80); h = r1(); w2(4);
-                        buf[i] = j44(l,h);
-                }
-                break;
-
-        case 1: w0(0x68); P1; w0(0);
-                for(i=0;i<count;i++) {
-                        w2(0x26); buf[i] = r0(); w2(0x24);
-                }
-               w2(4);
-               break;
-               
-       case 2: w3(0x68); (void)r1(); w2(0x24);
-               for (i=0;i<count;i++) buf[i] = r4();
-               w2(4);
-               break;
-
-        case 3: w3(0x68); (void)r1(); w2(0x24);
-                for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
-                w2(4);
-                break;
-
-        case 4: w3(0x68); (void)r1(); w2(0x24);
-                for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
-                w2(4);
-                break;
-               
-       }
-}
-
-/* NB: Watch out for the byte swapped writes ! */
-
-static void comm_write_block( PIA *pi, char * buf, int count )
-
-{       int    k;
-
-        switch (pi->mode) {
-
-        case 0:
-        case 1: w0(0x68); P1;
-               for (k=0;k<count;k++) {
-                        w2(5); w0(buf[k^1]); w2(7);
-                }
-                w2(5); w2(4);
-                break;
-
-        case 2: w3(0x48); (void)r1();
-                for (k=0;k<count;k++) w4(buf[k^1]);
-                break;
-
-        case 3: w3(0x48); (void)r1();
-                for (k=0;k<count/2;k++) w4w(pi_swab16(buf,k));
-                break;
-
-        case 4: w3(0x48); (void)r1();
-                for (k=0;k<count/4;k++) w4l(pi_swab32(buf,k));
-                break;
-
-
-        }
-}
-
-static void comm_log_adapter( PIA *pi, char * scratch, int verbose )
-
-{       char    *mode_string[5] = {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
-
-        printk("%s: comm %s, DataStor Commuter at 0x%x, ",
-                pi->device,COMM_VERSION,pi->port);
-        printk("mode %d (%s), delay %d\n",pi->mode,
-               mode_string[pi->mode],pi->delay);
-
-}
-
-static struct pi_protocol comm = {
-       .owner          = THIS_MODULE,
-       .name           = "comm",
-       .max_mode       = 5,
-       .epp_first      = 2,
-       .default_delay  = 1,
-       .max_units      = 1,
-       .write_regr     = comm_write_regr,
-       .read_regr      = comm_read_regr,
-       .write_block    = comm_write_block,
-       .read_block     = comm_read_block,
-       .connect        = comm_connect,
-       .disconnect     = comm_disconnect,
-       .log_adapter    = comm_log_adapter,
-};
-
-static int __init comm_init(void)
-{
-       return paride_register(&comm);
-}
-
-static void __exit comm_exit(void)
-{
-       paride_unregister(&comm);
-}
-
-MODULE_LICENSE("GPL");
-module_init(comm_init)
-module_exit(comm_exit)
diff --git a/drivers/block/paride/dstr.c b/drivers/block/paride/dstr.c
deleted file mode 100644 (file)
index edf414d..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-/* 
-        dstr.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                              Under the terms of the GNU General Public License.
-
-        dstr.c is a low-level protocol driver for the 
-        DataStor EP2000 parallel to IDE adapter chip.
-
-*/
-
-/* Changes:
-
-        1.01    GRG 1998.05.06 init_proto, release_proto
-
-*/
-
-#define DSTR_VERSION      "1.01"
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <asm/io.h>
-
-#include <linux/pata_parport.h>
-
-/* mode codes:  0  nybble reads, 8-bit writes
-                1  8-bit reads and writes
-                2  8-bit EPP mode
-               3  EPP-16
-               4  EPP-32
-*/
-
-#define j44(a,b)  (((a>>3)&0x07)|((~a>>4)&0x08)|((b<<1)&0x70)|((~b)&0x80))
-
-#define P1     w2(5);w2(0xd);w2(5);w2(4);
-#define P2     w2(5);w2(7);w2(5);w2(4);
-#define P3      w2(6);w2(4);w2(6);w2(4);
-
-/* cont = 0 - access the IDE register file 
-   cont = 1 - access the IDE command set 
-*/
-
-static int  cont_map[2] = { 0x20, 0x40 };
-
-static int dstr_read_regr( PIA *pi, int cont, int regr )
-
-{       int     a, b, r;
-
-        r = regr + cont_map[cont];
-
-       w0(0x81); P1;
-       if (pi->mode) { w0(0x11); } else { w0(1); }
-       P2; w0(r); P1;
-
-        switch (pi->mode)  {
-
-        case 0: w2(6); a = r1(); w2(4); w2(6); b = r1(); w2(4);
-                return j44(a,b);
-
-        case 1: w0(0); w2(0x26); a = r0(); w2(4);
-                return a;
-
-       case 2:
-       case 3:
-        case 4: w2(0x24); a = r4(); w2(4);
-                return a;
-
-        }
-        return -1;
-}       
-
-static void dstr_write_regr(  PIA *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);\
-                w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);w0(0x78);\
-                w0(x);w2(5);w2(4);
-
-static void dstr_connect ( PIA *pi  )
-
-{       pi->saved_r0 = r0();
-        pi->saved_r2 = r2();
-        w2(4); CCP(0xe0); w0(0xff);
-}
-
-static void dstr_disconnect ( PIA *pi )
-
-{       CCP(0x30);
-        w0(pi->saved_r0);
-        w2(pi->saved_r2);
-} 
-
-static void dstr_read_block( PIA *pi, char * buf, int count )
-
-{       int     k, a, b;
-
-        w0(0x81); P1;
-        if (pi->mode) { w0(0x19); } else { w0(9); }
-       P2; w0(0x82); P1; P3; w0(0x20); P1;
-
-        switch (pi->mode) {
-
-        case 0: for (k=0;k<count;k++) {
-                        w2(6); a = r1(); w2(4);
-                        w2(6); b = r1(); w2(4);
-                        buf[k] = j44(a,b);
-                } 
-                break;
-
-        case 1: w0(0);
-                for (k=0;k<count;k++) {
-                        w2(0x26); buf[k] = r0(); w2(0x24);
-                }
-                w2(4);
-                break;
-
-        case 2: w2(0x24); 
-                for (k=0;k<count;k++) buf[k] = r4();
-                w2(4);
-                break;
-
-        case 3: w2(0x24); 
-                for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
-                w2(4);
-                break;
-
-        case 4: w2(0x24); 
-                for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
-                w2(4);
-                break;
-
-        }
-}
-
-static void dstr_write_block( PIA *pi, char * buf, int count )
-
-{       int    k;
-
-        w0(0x81); P1;
-        if (pi->mode) { w0(0x19); } else { w0(9); }
-        P2; w0(0x82); P1; P3; w0(0x20); P1;
-
-        switch (pi->mode) {
-
-        case 0:
-        case 1: for (k=0;k<count;k++) {
-                        w2(5); w0(buf[k]); w2(7);
-                }
-                w2(5); w2(4);
-                break;
-
-        case 2: w2(0xc5);
-                for (k=0;k<count;k++) w4(buf[k]);
-               w2(0xc4);
-                break;
-
-        case 3: w2(0xc5);
-                for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
-                w2(0xc4);
-                break;
-
-        case 4: w2(0xc5);
-                for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
-                w2(0xc4);
-                break;
-
-        }
-}
-
-
-static void dstr_log_adapter( PIA *pi, char * scratch, int verbose )
-
-{       char    *mode_string[5] = {"4-bit","8-bit","EPP-8",
-                                  "EPP-16","EPP-32"};
-
-        printk("%s: dstr %s, DataStor EP2000 at 0x%x, ",
-                pi->device,DSTR_VERSION,pi->port);
-        printk("mode %d (%s), delay %d\n",pi->mode,
-               mode_string[pi->mode],pi->delay);
-
-}
-
-static struct pi_protocol dstr = {
-       .owner          = THIS_MODULE,
-       .name           = "dstr",
-       .max_mode       = 5,
-       .epp_first      = 2,
-       .default_delay  = 1,
-       .max_units      = 1,
-       .write_regr     = dstr_write_regr,
-       .read_regr      = dstr_read_regr,
-       .write_block    = dstr_write_block,
-       .read_block     = dstr_read_block,
-       .connect        = dstr_connect,
-       .disconnect     = dstr_disconnect,
-       .log_adapter    = dstr_log_adapter,
-};
-
-static int __init dstr_init(void)
-{
-       return paride_register(&dstr);
-}
-
-static void __exit dstr_exit(void)
-{
-       paride_unregister(&dstr);
-}
-
-MODULE_LICENSE("GPL");
-module_init(dstr_init)
-module_exit(dstr_exit)
diff --git a/drivers/block/paride/epat.c b/drivers/block/paride/epat.c
deleted file mode 100644 (file)
index 6ce2dee..0000000
+++ /dev/null
@@ -1,340 +0,0 @@
-/* 
-        epat.c  (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                            Under the terms of the GNU General Public License.
-
-       This is the low level protocol driver for the EPAT parallel
-        to IDE adapter from Shuttle Technologies.  This adapter is
-        used in many popular parallel port disk products such as the
-        SyQuest EZ drives, the Avatar Shark and the Imation SuperDisk.
-       
-*/
-
-/* Changes:
-
-        1.01    GRG 1998.05.06 init_proto, release_proto
-        1.02    Joshua b. Jore CPP(renamed), epat_connect, epat_disconnect
-
-*/
-
-#define EPAT_VERSION      "1.02"
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <asm/io.h>
-
-#include <linux/pata_parport.h>
-
-#define j44(a,b)               (((a>>4)&0x0f)+(b&0xf0))
-#define j53(a,b)               (((a>>3)&0x1f)+((b<<4)&0xe0))
-
-static int epatc8;
-
-module_param(epatc8, int, 0);
-MODULE_PARM_DESC(epatc8, "support for the Shuttle EP1284 chip, "
-       "used in any recent Imation SuperDisk (LS-120) drive.");
-
-/* cont =  0   IDE register file
-   cont =  1   IDE control registers
-   cont =  2   internal EPAT registers
-*/
-
-static int cont_map[3] = { 0x18, 0x10, 0 };
-
-static void epat_write_regr( PIA *pi, int cont, int regr, int val)
-
-{      int r;
-
-       r = regr + cont_map[cont];
-
-       switch (pi->mode) {
-
-       case 0:
-       case 1:
-       case 2: w0(0x60+r); w2(1); w0(val); w2(4);
-               break;
-
-       case 3:
-       case 4:
-       case 5: w3(0x40+r); w4(val);
-               break;
-
-       }
-}
-
-static int epat_read_regr( PIA *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();
-               return j44(a,b);
-
-       case 1: w0(0x40+r); w2(1); w2(4);
-               a = r1(); b = r2(); w0(0xff);
-               return j53(a,b);
-
-       case 2: w0(0x20+r); w2(1); w2(0x25);
-               a = r0(); w2(4);
-               return a;
-
-       case 3:
-       case 4:
-       case 5: w3(r); w2(0x24); a = r4(); w2(4);
-               return a;
-
-       }
-       return -1;      /* never gets here */
-}
-
-static void epat_read_block( PIA *pi, char * buf, int count )
-
-{      int  k, ph, a, b;
-
-       switch (pi->mode) {
-
-       case 0: w0(7); w2(1); w2(3); w0(0xff);
-               ph = 0;
-               for(k=0;k<count;k++) {
-                       if (k == count-1) w0(0xfd);
-                       w2(6+ph); a = r1();
-                       if (a & 8) b = a; 
-                         else { w2(4+ph); b = r1(); }
-                       buf[k] = j44(a,b);
-                       ph =  1 - ph;
-               }
-               w0(0); w2(4);
-               break;
-
-       case 1: w0(0x47); w2(1); w2(5); w0(0xff);
-               ph = 0;
-               for(k=0;k<count;k++) {
-                       if (k == count-1) w0(0xfd); 
-                       w2(4+ph);
-                       a = r1(); b = r2();
-                       buf[k] = j53(a,b);
-                       ph = 1 - ph;
-               }
-               w0(0); w2(4);
-               break;
-
-       case 2: w0(0x27); w2(1); w2(0x25); w0(0);
-               ph = 0;
-               for(k=0;k<count-1;k++) {
-                       w2(0x24+ph);
-                       buf[k] = r0();
-                       ph = 1 - ph;
-               }
-               w2(0x26); w2(0x27); buf[count-1] = r0(); 
-               w2(0x25); w2(4);
-               break;
-
-       case 3: w3(0x80); w2(0x24);
-               for(k=0;k<count-1;k++) buf[k] = r4();
-               w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
-               w2(4);
-               break;
-
-       case 4: w3(0x80); w2(0x24);
-               for(k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
-               buf[count-2] = r4();
-               w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
-               w2(4);
-               break;
-
-       case 5: w3(0x80); w2(0x24);
-               for(k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
-               for(k=count-4;k<count-1;k++) buf[k] = r4();
-               w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
-               w2(4);
-               break;
-
-       }
-}
-
-static void epat_write_block( PIA *pi, char * buf, int count )   
-
-{      int ph, k;
-
-       switch (pi->mode) {
-
-       case 0:
-       case 1:
-       case 2: w0(0x67); w2(1); w2(5);
-               ph = 0;
-               for(k=0;k<count;k++) {
-                       w0(buf[k]);
-                       w2(4+ph);
-                       ph = 1 - ph;
-               }
-               w2(7); w2(4);
-               break;
-
-       case 3: w3(0xc0); 
-               for(k=0;k<count;k++) w4(buf[k]);
-               w2(4);
-               break;
-
-       case 4: w3(0xc0); 
-               for(k=0;k<(count/2);k++) w4w(((u16 *)buf)[k]);
-               w2(4);
-               break;
-
-       case 5: w3(0xc0); 
-               for(k=0;k<(count/4);k++) w4l(((u32 *)buf)[k]);
-               w2(4);
-               break;
-
-       }
-}
-
-/* these macros access the EPAT registers in native addressing */
-
-#define        WR(r,v)         epat_write_regr(pi,2,r,v)
-#define        RR(r)           (epat_read_regr(pi,2,r))
-
-/* and these access the IDE task file */
-
-#define WRi(r,v)         epat_write_regr(pi,0,r,v)
-#define RRi(r)           (epat_read_regr(pi,0,r))
-
-/* FIXME:  the CPP stuff should be fixed to handle multiple EPATs on a chain */
-
-#define CPP(x)         w2(4);w0(0x22);w0(0xaa);w0(0x55);w0(0);w0(0xff);\
-                w0(0x87);w0(0x78);w0(x);w2(4);w2(5);w2(4);w0(0xff);
-
-static void epat_connect ( PIA *pi )
-
-{       pi->saved_r0 = r0();
-        pi->saved_r2 = r2();
-
-       /* Initialize the chip */
-       CPP(0);
-
-       if (epatc8) {
-               CPP(0x40);CPP(0xe0);
-               w0(0);w2(1);w2(4);
-               WR(0x8,0x12);WR(0xc,0x14);WR(0x12,0x10);
-               WR(0xe,0xf);WR(0xf,4);
-               /* WR(0xe,0xa);WR(0xf,4); */
-               WR(0xe,0xd);WR(0xf,0);
-               /* CPP(0x30); */
-       }
-
-        /* Connect to the chip */
-       CPP(0xe0);
-        w0(0);w2(1);w2(4); /* Idle into SPP */
-        if (pi->mode >= 3) {
-          w0(0);w2(1);w2(4);w2(0xc);
-          /* Request EPP */
-          w0(0x40);w2(6);w2(7);w2(4);w2(0xc);w2(4);
-        }
-
-       if (!epatc8) {
-               WR(8,0x10); WR(0xc,0x14); WR(0xa,0x38); WR(0x12,0x10);
-       }
-}
-
-static void epat_disconnect (PIA *pi)
-{      CPP(0x30);
-       w0(pi->saved_r0);
-       w2(pi->saved_r2);
-}
-
-static int epat_test_proto( PIA *pi, char * scratch, int verbose )
-
-{       int     k, j, f, cc;
-       int     e[2] = {0,0};
-
-        epat_connect(pi);
-       cc = RR(0xd);
-       epat_disconnect(pi);
-
-       epat_connect(pi);
-       for (j=0;j<2;j++) {
-           WRi(6,0xa0+j*0x10);
-            for (k=0;k<256;k++) {
-                WRi(2,k^0xaa);
-                WRi(3,k^0x55);
-                if (RRi(2) != (k^0xaa)) e[j]++;
-                }
-           }
-        epat_disconnect(pi);
-
-        f = 0;
-        epat_connect(pi);
-        WR(0x13,1); WR(0x13,0); WR(0xa,0x11);
-        epat_read_block(pi,scratch,512);
-       
-        for (k=0;k<256;k++) {
-            if ((scratch[2*k] & 0xff) != k) f++;
-            if ((scratch[2*k+1] & 0xff) != (0xff-k)) f++;
-        }
-        epat_disconnect(pi);
-
-        if (verbose)  {
-            printk("%s: epat: port 0x%x, mode %d, ccr %x, test=(%d,%d,%d)\n",
-                  pi->device,pi->port,pi->mode,cc,e[0],e[1],f);
-       }
-       
-        return (e[0] && e[1]) || f;
-}
-
-static void epat_log_adapter( PIA *pi, char * scratch, int verbose )
-
-{      int     ver;
-        char    *mode_string[6] = 
-                  {"4-bit","5/3","8-bit","EPP-8","EPP-16","EPP-32"};
-
-       epat_connect(pi);
-       WR(0xa,0x38);           /* read the version code */
-        ver = RR(0xb);
-        epat_disconnect(pi);
-
-       printk("%s: epat %s, Shuttle EPAT chip %x at 0x%x, ",
-               pi->device,EPAT_VERSION,ver,pi->port);
-       printk("mode %d (%s), delay %d\n",pi->mode,
-               mode_string[pi->mode],pi->delay);
-
-}
-
-static struct pi_protocol epat = {
-       .owner          = THIS_MODULE,
-       .name           = "epat",
-       .max_mode       = 6,
-       .epp_first      = 3,
-       .default_delay  = 1,
-       .max_units      = 1,
-       .write_regr     = epat_write_regr,
-       .read_regr      = epat_read_regr,
-       .write_block    = epat_write_block,
-       .read_block     = epat_read_block,
-       .connect        = epat_connect,
-       .disconnect     = epat_disconnect,
-       .test_proto     = epat_test_proto,
-       .log_adapter    = epat_log_adapter,
-};
-
-static int __init epat_init(void)
-{
-#ifdef CONFIG_PARIDE_EPATC8
-       epatc8 = 1;
-#endif
-       return paride_register(&epat);
-}
-
-static void __exit epat_exit(void)
-{
-       paride_unregister(&epat);
-}
-
-MODULE_LICENSE("GPL");
-module_init(epat_init)
-module_exit(epat_exit)
diff --git a/drivers/block/paride/epia.c b/drivers/block/paride/epia.c
deleted file mode 100644 (file)
index 417d5a3..0000000
+++ /dev/null
@@ -1,316 +0,0 @@
-/* 
-        epia.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                              Under the terms of the GNU General Public License.
-
-        epia.c is a low-level protocol driver for Shuttle Technologies 
-       EPIA parallel to IDE adapter chip.  This device is now obsolete
-       and has been replaced with the EPAT chip, which is supported
-       by epat.c, however, some devices based on EPIA are still
-       available.
-
-*/
-
-/* Changes:
-
-        1.01    GRG 1998.05.06 init_proto, release_proto
-       1.02    GRG 1998.06.17 support older versions of EPIA
-
-*/
-
-#define EPIA_VERSION      "1.02"
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <asm/io.h>
-
-#include <linux/pata_parport.h>
-
-/* mode codes:  0  nybble reads on port 1, 8-bit writes
-                1  5/3 reads on ports 1 & 2, 8-bit writes
-                2  8-bit reads and writes
-                3  8-bit EPP mode
-               4  16-bit EPP
-               5  32-bit EPP
-*/
-
-#define j44(a,b)                (((a>>4)&0x0f)+(b&0xf0))
-#define j53(a,b)                (((a>>3)&0x1f)+((b<<4)&0xe0))
-
-/* cont =  0   IDE register file
-   cont =  1   IDE control registers
-*/
-
-static int cont_map[2] = { 0, 0x80 };
-
-static int epia_read_regr( PIA *pi, int cont, int regr )
-
-{       int     a, b, r;
-
-       regr += cont_map[cont];
-
-        switch (pi->mode)  {
-
-        case 0: r = regr^0x39;
-                w0(r); w2(1); w2(3); w0(r);
-                a = r1(); w2(1); b = r1(); w2(4);
-                return j44(a,b);
-
-        case 1: r = regr^0x31;
-                w0(r); w2(1); w0(r&0x37); 
-                w2(3); w2(5); w0(r|0xf0);
-                a = r1(); b = r2(); w2(4);
-                return j53(a,b);
-
-        case 2: r = regr^0x29;
-                w0(r); w2(1); w2(0X21); w2(0x23); 
-                a = r0(); w2(4);
-                return a;
-
-       case 3:
-       case 4:
-        case 5: w3(regr); w2(0x24); a = r4(); w2(4);
-                return a;
-
-        }
-        return -1;
-}       
-
-static void epia_write_regr( PIA *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)
-#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 ( PIA *pi  )
-
-{       pi->saved_r0 = r0();
-        pi->saved_r2 = r2();
-
-        w2(4); w0(0xa0); w0(0x50); w0(0xc0); w0(0x30); w0(0xa0); w0(0);
-        w2(1); w2(4);
-        if (pi->mode >= 3) { 
-                w0(0xa); w2(1); w2(4); w0(0x82); w2(4); w2(0xc); w2(4);
-                w2(0x24); w2(0x26); w2(4);
-        }
-        WR(0x86,8);  
-}
-
-static void epia_disconnect ( PIA *pi )
-
-{       /* WR(0x84,0x10); */
-        w0(pi->saved_r0);
-        w2(1); w2(4);
-        w0(pi->saved_r0);
-        w2(pi->saved_r2);
-} 
-
-static void epia_read_block( PIA *pi, char * buf, int count )
-
-{       int     k, ph, a, b;
-
-        switch (pi->mode) {
-
-        case 0: w0(0x81); w2(1); w2(3); w0(0xc1);
-                ph = 1;
-                for (k=0;k<count;k++) {
-                        w2(2+ph); a = r1();
-                        w2(4+ph); b = r1();
-                        buf[k] = j44(a,b);
-                        ph = 1 - ph;
-                } 
-                w0(0); w2(4);
-                break;
-
-        case 1: w0(0x91); w2(1); w0(0x10); w2(3); 
-                w0(0x51); w2(5); w0(0xd1); 
-                ph = 1;
-                for (k=0;k<count;k++) {
-                        w2(4+ph);
-                        a = r1(); b = r2();
-                        buf[k] = j53(a,b);
-                        ph = 1 - ph;
-                }
-                w0(0); w2(4);
-                break;
-
-        case 2: w0(0x89); w2(1); w2(0x23); w2(0x21); 
-                ph = 1;
-                for (k=0;k<count;k++) {
-                        w2(0x24+ph);
-                        buf[k] = r0();
-                        ph = 1 - ph;
-                }
-                w2(6); w2(4);
-                break;
-
-        case 3: if (count > 512) WR(0x84,3);
-               w3(0); w2(0x24);
-                for (k=0;k<count;k++) buf[k] = r4();
-                w2(4); WR(0x84,0);
-                break;
-
-        case 4: if (count > 512) WR(0x84,3);
-               w3(0); w2(0x24);
-               for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
-                w2(4); WR(0x84,0);
-                break;
-
-        case 5: if (count > 512) WR(0x84,3);
-               w3(0); w2(0x24);
-                for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
-                w2(4); WR(0x84,0);
-                break;
-
-        }
-}
-
-static void epia_write_block( PIA *pi, char * buf, int count )
-
-{       int     ph, k, last, d;
-
-        switch (pi->mode) {
-
-        case 0:
-        case 1:
-        case 2: w0(0xa1); w2(1); w2(3); w2(1); w2(5);
-                ph = 0;  last = 0x8000;
-                for (k=0;k<count;k++) {
-                        d = buf[k];
-                        if (d != last) { last = d; w0(d); }
-                        w2(4+ph);
-                        ph = 1 - ph;
-                }
-                w2(7); w2(4);
-                break;
-
-        case 3: if (count < 512) WR(0x84,1);
-               w3(0x40);
-                for (k=0;k<count;k++) w4(buf[k]);
-               if (count < 512) WR(0x84,0);
-                break;
-
-        case 4: if (count < 512) WR(0x84,1);
-               w3(0x40);
-                for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
-               if (count < 512) WR(0x84,0);
-                break;
-
-        case 5: if (count < 512) WR(0x84,1);
-               w3(0x40);
-                for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
-               if (count < 512) WR(0x84,0);
-                break;
-
-        }
-
-}
-
-static int epia_test_proto( PIA *pi, char * scratch, int verbose )
-
-{       int     j, k, f;
-       int     e[2] = {0,0};
-
-        epia_connect(pi);
-        for (j=0;j<2;j++) {
-            WR(6,0xa0+j*0x10);
-            for (k=0;k<256;k++) {
-                WR(2,k^0xaa);
-                WR(3,k^0x55);
-                if (RR(2) != (k^0xaa)) e[j]++;
-                }
-           WR(2,1); WR(3,1);
-            }
-        epia_disconnect(pi);
-
-        f = 0;
-        epia_connect(pi);
-        WR(0x84,8);
-        epia_read_block(pi,scratch,512);
-        for (k=0;k<256;k++) {
-            if ((scratch[2*k] & 0xff) != ((k+1) & 0xff)) f++;
-            if ((scratch[2*k+1] & 0xff) != ((-2-k) & 0xff)) f++;
-        }
-        WR(0x84,0);
-        epia_disconnect(pi);
-
-        if (verbose)  {
-            printk("%s: epia: port 0x%x, mode %d, test=(%d,%d,%d)\n",
-                   pi->device,pi->port,pi->mode,e[0],e[1],f);
-        }
-        
-        return (e[0] && e[1]) || f;
-
-}
-
-
-static void epia_log_adapter( PIA *pi, char * scratch, int verbose )
-
-{       char    *mode_string[6] = {"4-bit","5/3","8-bit",
-                                  "EPP-8","EPP-16","EPP-32"};
-
-        printk("%s: epia %s, Shuttle EPIA at 0x%x, ",
-                pi->device,EPIA_VERSION,pi->port);
-        printk("mode %d (%s), delay %d\n",pi->mode,
-               mode_string[pi->mode],pi->delay);
-
-}
-
-static struct pi_protocol epia = {
-       .owner          = THIS_MODULE,
-       .name           = "epia",
-       .max_mode       = 6,
-       .epp_first      = 3,
-       .default_delay  = 1,
-       .max_units      = 1,
-       .write_regr     = epia_write_regr,
-       .read_regr      = epia_read_regr,
-       .write_block    = epia_write_block,
-       .read_block     = epia_read_block,
-       .connect        = epia_connect,
-       .disconnect     = epia_disconnect,
-       .test_proto     = epia_test_proto,
-       .log_adapter    = epia_log_adapter,
-};
-
-static int __init epia_init(void)
-{
-       return paride_register(&epia);
-}
-
-static void __exit epia_exit(void)
-{
-       paride_unregister(&epia);
-}
-
-MODULE_LICENSE("GPL");
-module_init(epia_init)
-module_exit(epia_exit)
diff --git a/drivers/block/paride/fit2.c b/drivers/block/paride/fit2.c
deleted file mode 100644 (file)
index 3c7a106..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/* 
-        fit2.c        (c) 1998  Grant R. Guenther <grant@torque.net>
-                          Under the terms of the GNU General Public License.
-
-       fit2.c is a low-level protocol driver for the older version
-        of the Fidelity International Technology parallel port adapter.  
-       This adapter is used in their TransDisk 2000 and older TransDisk
-       3000 portable hard-drives.  As far as I can tell, this device
-       supports 4-bit mode _only_.  
-
-       Newer models of the FIT products use an enhanced protocol.
-       The "fit3" protocol module should support current drives.
-
-*/
-
-#define FIT2_VERSION      "1.0"
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <asm/io.h>
-
-#include <linux/pata_parport.h>
-
-#define j44(a,b)                (((a>>4)&0x0f)|(b&0xf0))
-
-/* cont = 0 - access the IDE register file 
-   cont = 1 - access the IDE command set 
-
-NB:  The FIT adapter does not appear to use the control registers.
-So, we map ALT_STATUS to STATUS and NO-OP writes to the device
-control register - this means that IDE reset will not work on these
-devices.
-
-*/
-
-static void  fit2_write_regr( PIA *pi, int cont, int regr, int val)
-
-{      if (cont == 1) return;
-       w2(0xc); w0(regr); w2(4); w0(val); w2(5); w0(0); w2(4);
-}
-
-static int fit2_read_regr( PIA *pi, int cont, int regr )
-
-{      int  a, b, r;
-
-       if (cont) {
-         if (regr != 6) return 0xff;
-         r = 7;
-       } else r = regr + 0x10;
-
-       w2(0xc); w0(r); w2(4); w2(5); 
-                w0(0); a = r1();
-                w0(1); b = r1();
-       w2(4);
-
-       return j44(a,b);
-
-}
-
-static void fit2_read_block( PIA *pi, char * buf, int count )
-
-{      int  k, a, b, c, d;
-
-       w2(0xc); w0(0x10);
-
-       for (k=0;k<count/4;k++) {
-
-               w2(4); w2(5);
-               w0(0); a = r1(); w0(1); b = r1();
-               w0(3); c = r1(); w0(2); d = r1(); 
-               buf[4*k+0] = j44(a,b);
-               buf[4*k+1] = j44(d,c);
-
-                w2(4); w2(5);
-                       a = r1(); w0(3); b = r1();
-                w0(1); c = r1(); w0(0); d = r1(); 
-                buf[4*k+2] = j44(d,c);
-                buf[4*k+3] = j44(a,b);
-
-       }
-
-       w2(4);
-
-}
-
-static void fit2_write_block( PIA *pi, char * buf, int count )
-
-{      int k;
-
-
-       w2(0xc); w0(0); 
-       for (k=0;k<count/2;k++) {
-               w2(4); w0(buf[2*k]); 
-               w2(5); w0(buf[2*k+1]);
-       }
-       w2(4);
-}
-
-static void fit2_connect ( PIA *pi  )
-
-{       pi->saved_r0 = r0();
-        pi->saved_r2 = r2();
-       w2(0xcc); 
-}
-
-static void fit2_disconnect ( PIA *pi )
-
-{       w0(pi->saved_r0);
-        w2(pi->saved_r2);
-} 
-
-static void fit2_log_adapter( PIA *pi, char * scratch, int verbose )
-
-{       printk("%s: fit2 %s, FIT 2000 adapter at 0x%x, delay %d\n",
-                pi->device,FIT2_VERSION,pi->port,pi->delay);
-
-}
-
-static struct pi_protocol fit2 = {
-       .owner          = THIS_MODULE,
-       .name           = "fit2",
-       .max_mode       = 1,
-       .epp_first      = 2,
-       .default_delay  = 1,
-       .max_units      = 1,
-       .write_regr     = fit2_write_regr,
-       .read_regr      = fit2_read_regr,
-       .write_block    = fit2_write_block,
-       .read_block     = fit2_read_block,
-       .connect        = fit2_connect,
-       .disconnect     = fit2_disconnect,
-       .log_adapter    = fit2_log_adapter,
-};
-
-static int __init fit2_init(void)
-{
-       return paride_register(&fit2);
-}
-
-static void __exit fit2_exit(void)
-{
-       paride_unregister(&fit2);
-}
-
-MODULE_LICENSE("GPL");
-module_init(fit2_init)
-module_exit(fit2_exit)
diff --git a/drivers/block/paride/fit3.c b/drivers/block/paride/fit3.c
deleted file mode 100644 (file)
index cd95f4f..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-/* 
-        fit3.c        (c) 1998  Grant R. Guenther <grant@torque.net>
-                          Under the terms of the GNU General Public License.
-
-       fit3.c is a low-level protocol driver for newer models 
-        of the Fidelity International Technology parallel port adapter.  
-       This adapter is used in their TransDisk 3000 portable 
-       hard-drives, as well as CD-ROM, PD-CD and other devices.
-
-       The TD-2000 and certain older devices use a different protocol.
-       Try the fit2 protocol module with them.
-
-        NB:  The FIT adapters do not appear to support the control 
-       registers.  So, we map ALT_STATUS to STATUS and NO-OP writes 
-       to the device control register - this means that IDE reset 
-       will not work on these devices.
-
-*/
-
-#define FIT3_VERSION      "1.0"
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <asm/io.h>
-
-#include <linux/pata_parport.h>
-
-#define j44(a,b)                (((a>>3)&0x0f)|((b<<1)&0xf0))
-
-#define w7(byte)                {out_p(7,byte);}
-#define r7()                    (in_p(7) & 0xff)
-
-/* cont = 0 - access the IDE register file 
-   cont = 1 - access the IDE command set 
-
-*/
-
-static void  fit3_write_regr( PIA *pi, int cont, int regr, int val)
-
-{      if (cont == 1) return;
-
-       switch (pi->mode) {
-
-       case 0:
-       case 1: w2(0xc); w0(regr); w2(0x8); w2(0xc); 
-               w0(val); w2(0xd); 
-               w0(0);   w2(0xc);
-               break;
-
-       case 2: w2(0xc); w0(regr); w2(0x8); w2(0xc);
-               w4(val); w4(0);
-               w2(0xc);
-               break;
-
-       }
-}
-
-static int fit3_read_regr( PIA *pi, int cont, int regr )
-
-{      int  a, b;
-
-       if (cont) {
-         if (regr != 6) return 0xff;
-         regr = 7;
-       } 
-
-       switch (pi->mode) {
-
-       case 0: w2(0xc); w0(regr + 0x10); w2(0x8); w2(0xc);
-               w2(0xd); a = r1();
-               w2(0xf); b = r1(); 
-               w2(0xc);
-               return j44(a,b);
-
-       case 1: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc);
-               w2(0xec); w2(0xee); w2(0xef); a = r0(); 
-               w2(0xc);
-               return a;
-
-       case 2: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc); 
-               w2(0xec); 
-               a = r4(); b = r4(); 
-               w2(0xc);
-               return a;
-
-       }
-       return -1; 
-
-}
-
-static void fit3_read_block( PIA *pi, char * buf, int count )
-
-{      int  k, a, b, c, d;
-
-       switch (pi->mode) {
-
-       case 0: w2(0xc); w0(0x10); w2(0x8); w2(0xc);
-               for (k=0;k<count/2;k++) {
-                   w2(0xd); a = r1();
-                   w2(0xf); b = r1();
-                   w2(0xc); c = r1();
-                   w2(0xe); d = r1();
-                   buf[2*k  ] = j44(a,b);
-                   buf[2*k+1] = j44(c,d);
-               }
-               w2(0xc);
-               break;
-
-       case 1: w2(0xc); w0(0x90); w2(0x8); w2(0xc); 
-               w2(0xec); w2(0xee);
-               for (k=0;k<count/2;k++) {
-                   w2(0xef); a = r0();
-                   w2(0xee); b = r0();
-                    buf[2*k  ] = a;
-                    buf[2*k+1] = b;
-               }
-               w2(0xec); 
-               w2(0xc);
-               break;
-
-       case 2: w2(0xc); w0(0x90); w2(0x8); w2(0xc); 
-                w2(0xec);
-               for (k=0;k<count;k++) buf[k] = r4();
-                w2(0xc);
-               break;
-
-       }
-}
-
-static void fit3_write_block( PIA *pi, char * buf, int count )
-
-{      int k;
-
-        switch (pi->mode) {
-
-       case 0:
-        case 1: w2(0xc); w0(0); w2(0x8); w2(0xc);
-                for (k=0;k<count/2;k++) {
-                   w0(buf[2*k  ]); w2(0xd);
-                   w0(buf[2*k+1]); w2(0xc);
-               }
-               break;
-
-        case 2: w2(0xc); w0(0); w2(0x8); w2(0xc); 
-                for (k=0;k<count;k++) w4(buf[k]);
-                w2(0xc);
-               break;
-       }
-}
-
-static void fit3_connect ( PIA *pi  )
-
-{       pi->saved_r0 = r0();
-        pi->saved_r2 = r2();
-       w2(0xc); w0(0); w2(0xa);
-       if (pi->mode == 2) { 
-               w2(0xc); w0(0x9); w2(0x8); w2(0xc); 
-               }
-}
-
-static void fit3_disconnect ( PIA *pi )
-
-{       w2(0xc); w0(0xa); w2(0x8); w2(0xc);
-       w0(pi->saved_r0);
-        w2(pi->saved_r2);
-} 
-
-static void fit3_log_adapter( PIA *pi, char * scratch, int verbose )
-
-{       char    *mode_string[3] = {"4-bit","8-bit","EPP"};
-
-       printk("%s: fit3 %s, FIT 3000 adapter at 0x%x, "
-              "mode %d (%s), delay %d\n",
-                pi->device,FIT3_VERSION,pi->port,
-               pi->mode,mode_string[pi->mode],pi->delay);
-
-}
-
-static struct pi_protocol fit3 = {
-       .owner          = THIS_MODULE,
-       .name           = "fit3",
-       .max_mode       = 3,
-       .epp_first      = 2,
-       .default_delay  = 1,
-       .max_units      = 1,
-       .write_regr     = fit3_write_regr,
-       .read_regr      = fit3_read_regr,
-       .write_block    = fit3_write_block,
-       .read_block     = fit3_read_block,
-       .connect        = fit3_connect,
-       .disconnect     = fit3_disconnect,
-       .log_adapter    = fit3_log_adapter,
-};
-
-static int __init fit3_init(void)
-{
-       return paride_register(&fit3);
-}
-
-static void __exit fit3_exit(void)
-{
-       paride_unregister(&fit3);
-}
-
-MODULE_LICENSE("GPL");
-module_init(fit3_init)
-module_exit(fit3_exit)
diff --git a/drivers/block/paride/friq.c b/drivers/block/paride/friq.c
deleted file mode 100644 (file)
index da1d0cb..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/* 
-       friq.c  (c) 1998    Grant R. Guenther <grant@torque.net>
-                           Under the terms of the GNU General Public License
-
-       friq.c is a low-level protocol driver for the Freecom "IQ"
-       parallel port IDE adapter.   Early versions of this adapter
-       use the 'frpw' protocol.
-       
-       Freecom uses this adapter in a battery powered external 
-       CD-ROM drive.  It is also used in LS-120 drives by
-       Maxell and Panasonic, and other devices.
-
-       The battery powered drive requires software support to
-       control the power to the drive.  This module enables the
-       drive power when the high level driver (pcd) is loaded
-       and disables it when the module is unloaded.  Note, if
-       the friq module is built in to the kernel, the power
-       will never be switched off, so other means should be
-       used to conserve battery power.
-
-*/
-
-/* Changes:
-
-       1.01    GRG 1998.12.20   Added support for soft power switch
-*/
-
-#define        FRIQ_VERSION    "1.01" 
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <asm/io.h>
-
-#include <linux/pata_parport.h>
-
-#define CMD(x)         w2(4);w0(0xff);w0(0xff);w0(0x73);w0(0x73);\
-                       w0(0xc9);w0(0xc9);w0(0x26);w0(0x26);w0(x);w0(x);
-
-#define j44(l,h)       (((l>>4)&0x0f)|(h&0xf0))
-
-/* cont = 0 - access the IDE register file 
-   cont = 1 - access the IDE command set 
-*/
-
-static int  cont_map[2] = { 0x08, 0x10 };
-
-static int friq_read_regr( PIA *pi, int cont, int regr )
-
-{      int     h,l,r;
-
-       r = regr + cont_map[cont];
-
-       CMD(r);
-       w2(6); l = r1();
-       w2(4); h = r1();
-       w2(4); 
-
-       return j44(l,h);
-
-}
-
-static void friq_write_regr( PIA *pi, int cont, int regr, int val)
-
-{      int r;
-
-        r = regr + cont_map[cont];
-
-       CMD(r);
-       w0(val);
-       w2(5);w2(7);w2(5);w2(4);
-}
-
-static void friq_read_block_int( PIA *pi, char * buf, int count, int regr )
-
-{       int     h, l, k, ph;
-
-        switch(pi->mode) {
-
-        case 0: CMD(regr); 
-                for (k=0;k<count;k++) {
-                        w2(6); l = r1();
-                        w2(4); h = r1();
-                        buf[k] = j44(l,h);
-                }
-                w2(4);
-                break;
-
-        case 1: ph = 2;
-                CMD(regr+0xc0); 
-                w0(0xff);
-                for (k=0;k<count;k++) {
-                        w2(0xa4 + ph); 
-                        buf[k] = r0();
-                        ph = 2 - ph;
-                } 
-                w2(0xac); w2(0xa4); w2(4);
-                break;
-
-       case 2: CMD(regr+0x80);
-               for (k=0;k<count-2;k++) buf[k] = r4();
-               w2(0xac); w2(0xa4);
-               buf[count-2] = r4();
-               buf[count-1] = r4();
-               w2(4);
-               break;
-
-       case 3: CMD(regr+0x80);
-                for (k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
-                w2(0xac); w2(0xa4);
-                buf[count-2] = r4();
-                buf[count-1] = r4();
-                w2(4);
-                break;
-
-       case 4: CMD(regr+0x80);
-                for (k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
-                buf[count-4] = r4();
-                buf[count-3] = r4();
-                w2(0xac); w2(0xa4);
-                buf[count-2] = r4();
-                buf[count-1] = r4();
-                w2(4);
-                break;
-
-        }
-}
-
-static void friq_read_block( PIA *pi, char * buf, int count)
-
-{      friq_read_block_int(pi,buf,count,0x08);
-}
-
-static void friq_write_block( PIA *pi, char * buf, int count )
-{      int     k;
-
-       switch(pi->mode) {
-
-       case 0:
-       case 1: CMD(8); w2(5);
-               for (k=0;k<count;k++) {
-                       w0(buf[k]);
-                       w2(7);w2(5);
-               }
-               w2(4);
-               break;
-
-       case 2: CMD(0xc8); w2(5);
-               for (k=0;k<count;k++) w4(buf[k]);
-               w2(4);
-               break;
-
-        case 3: CMD(0xc8); w2(5);
-                for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
-                w2(4);
-                break;
-
-        case 4: CMD(0xc8); w2(5);
-                for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
-                w2(4);
-                break;
-       }
-}
-
-static void friq_connect ( PIA *pi  )
-
-{       pi->saved_r0 = r0();
-        pi->saved_r2 = r2();
-       w2(4);
-}
-
-static void friq_disconnect ( PIA *pi )
-
-{       CMD(0x20);
-       w0(pi->saved_r0);
-        w2(pi->saved_r2);
-} 
-
-static int friq_test_proto( PIA *pi, char * scratch, int verbose )
-
-{       int     j, k, r;
-       int     e[2] = {0,0};
-
-       pi->saved_r0 = r0();    
-       w0(0xff); udelay(20); CMD(0x3d); /* turn the power on */
-       udelay(500);
-       w0(pi->saved_r0);
-
-       friq_connect(pi);
-       for (j=0;j<2;j++) {
-                friq_write_regr(pi,0,6,0xa0+j*0x10);
-                for (k=0;k<256;k++) {
-                        friq_write_regr(pi,0,2,k^0xaa);
-                        friq_write_regr(pi,0,3,k^0x55);
-                        if (friq_read_regr(pi,0,2) != (k^0xaa)) e[j]++;
-                        }
-                }
-       friq_disconnect(pi);
-
-       friq_connect(pi);
-        friq_read_block_int(pi,scratch,512,0x10);
-        r = 0;
-        for (k=0;k<128;k++) if (scratch[k] != k) r++;
-       friq_disconnect(pi);
-
-        if (verbose)  {
-            printk("%s: friq: port 0x%x, mode %d, test=(%d,%d,%d)\n",
-                   pi->device,pi->port,pi->mode,e[0],e[1],r);
-        }
-
-        return (r || (e[0] && e[1]));
-}
-
-
-static void friq_log_adapter( PIA *pi, char * scratch, int verbose )
-
-{       char    *mode_string[6] = {"4-bit","8-bit",
-                                  "EPP-8","EPP-16","EPP-32"};
-
-        printk("%s: friq %s, Freecom IQ ASIC-2 adapter at 0x%x, ", pi->device,
-               FRIQ_VERSION,pi->port);
-        printk("mode %d (%s), delay %d\n",pi->mode,
-               mode_string[pi->mode],pi->delay);
-
-       pi->private = 1;
-       friq_connect(pi);
-       CMD(0x9e);              /* disable sleep timer */
-       friq_disconnect(pi);
-
-}
-
-static void friq_release_proto( PIA *pi)
-{
-       if (pi->private) {              /* turn off the power */
-               friq_connect(pi);
-               CMD(0x1d); CMD(0x1e);
-               friq_disconnect(pi);
-               pi->private = 0;
-       }
-}
-
-static struct pi_protocol friq = {
-       .owner          = THIS_MODULE,
-       .name           = "friq",
-       .max_mode       = 5,
-       .epp_first      = 2,
-       .default_delay  = 1,
-       .max_units      = 1,
-       .write_regr     = friq_write_regr,
-       .read_regr      = friq_read_regr,
-       .write_block    = friq_write_block,
-       .read_block     = friq_read_block,
-       .connect        = friq_connect,
-       .disconnect     = friq_disconnect,
-       .test_proto     = friq_test_proto,
-       .log_adapter    = friq_log_adapter,
-       .release_proto  = friq_release_proto,
-};
-
-static int __init friq_init(void)
-{
-       return paride_register(&friq);
-}
-
-static void __exit friq_exit(void)
-{
-       paride_unregister(&friq);
-}
-
-MODULE_LICENSE("GPL");
-module_init(friq_init)
-module_exit(friq_exit)
diff --git a/drivers/block/paride/frpw.c b/drivers/block/paride/frpw.c
deleted file mode 100644 (file)
index 7bc8fa1..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-/* 
-       frpw.c  (c) 1996-8  Grant R. Guenther <grant@torque.net>
-                           Under the terms of the GNU General Public License
-
-       frpw.c is a low-level protocol driver for the Freecom "Power"
-       parallel port IDE adapter.
-       
-       Some applications of this adapter may require a "printer" reset
-       prior to loading the driver.  This can be done by loading and
-       unloading the "lp" driver, or it can be done by this driver
-       if you define FRPW_HARD_RESET.  The latter is not recommended
-       as it may upset devices on other ports.
-
-*/
-
-/* Changes:
-
-        1.01    GRG 1998.05.06 init_proto, release_proto
-                              fix chip detect
-                              added EPP-16 and EPP-32
-       1.02    GRG 1998.09.23 added hard reset to initialisation process
-       1.03    GRG 1998.12.14 made hard reset conditional
-
-*/
-
-#define        FRPW_VERSION    "1.03" 
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <asm/io.h>
-
-#include <linux/pata_parport.h>
-
-#define cec4           w2(0xc);w2(0xe);w2(0xe);w2(0xc);w2(4);w2(4);w2(4);
-#define j44(l,h)       (((l>>4)&0x0f)|(h&0xf0))
-
-/* cont = 0 - access the IDE register file 
-   cont = 1 - access the IDE command set 
-*/
-
-static int  cont_map[2] = { 0x08, 0x10 };
-
-static int frpw_read_regr( PIA *pi, int cont, int regr )
-
-{      int     h,l,r;
-
-       r = regr + cont_map[cont];
-
-       w2(4);
-       w0(r); cec4;
-       w2(6); l = r1();
-       w2(4); h = r1();
-       w2(4); 
-
-       return j44(l,h);
-
-}
-
-static void frpw_write_regr( PIA *pi, int cont, int regr, int val)
-
-{      int r;
-
-        r = regr + cont_map[cont];
-
-       w2(4); w0(r); cec4; 
-       w0(val);
-       w2(5);w2(7);w2(5);w2(4);
-}
-
-static void frpw_read_block_int( PIA *pi, char * buf, int count, int regr )
-
-{       int     h, l, k, ph;
-
-        switch(pi->mode) {
-
-        case 0: w2(4); w0(regr); cec4;
-                for (k=0;k<count;k++) {
-                        w2(6); l = r1();
-                        w2(4); h = r1();
-                        buf[k] = j44(l,h);
-                }
-                w2(4);
-                break;
-
-        case 1: ph = 2;
-                w2(4); w0(regr + 0xc0); cec4;
-                w0(0xff);
-                for (k=0;k<count;k++) {
-                        w2(0xa4 + ph); 
-                        buf[k] = r0();
-                        ph = 2 - ph;
-                } 
-                w2(0xac); w2(0xa4); w2(4);
-                break;
-
-        case 2: w2(4); w0(regr + 0x80); cec4;
-                for (k=0;k<count;k++) buf[k] = r4();
-                w2(0xac); w2(0xa4);
-                w2(4);
-                break;
-
-       case 3: w2(4); w0(regr + 0x80); cec4;
-               for (k=0;k<count-2;k++) buf[k] = r4();
-               w2(0xac); w2(0xa4);
-               buf[count-2] = r4();
-               buf[count-1] = r4();
-               w2(4);
-               break;
-
-       case 4: w2(4); w0(regr + 0x80); cec4;
-                for (k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
-                w2(0xac); w2(0xa4);
-                buf[count-2] = r4();
-                buf[count-1] = r4();
-                w2(4);
-                break;
-
-       case 5: w2(4); w0(regr + 0x80); cec4;
-                for (k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
-                buf[count-4] = r4();
-                buf[count-3] = r4();
-                w2(0xac); w2(0xa4);
-                buf[count-2] = r4();
-                buf[count-1] = r4();
-                w2(4);
-                break;
-
-        }
-}
-
-static void frpw_read_block( PIA *pi, char * buf, int count)
-
-{      frpw_read_block_int(pi,buf,count,0x08);
-}
-
-static void frpw_write_block( PIA *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 ( PIA *pi  )
-
-{       pi->saved_r0 = r0();
-        pi->saved_r2 = r2();
-       w2(4);
-}
-
-static void frpw_disconnect ( PIA *pi )
-
-{       w2(4); w0(0x20); cec4;
-       w0(pi->saved_r0);
-        w2(pi->saved_r2);
-} 
-
-/* Stub logic to see if PNP string is available - used to distinguish
-   between the Xilinx and ASIC implementations of the Freecom adapter.
-*/
-
-static int frpw_test_pnp ( PIA *pi )
-
-/*  returns chip_type:   0 = Xilinx, 1 = ASIC   */
-
-{      int olddelay, a, b;
-
-#ifdef FRPW_HARD_RESET
-        w0(0); w2(8); udelay(50); w2(0xc);   /* parallel bus reset */
-        mdelay(1500);
-#endif
-
-       olddelay = pi->delay;
-       pi->delay = 10;
-
-       pi->saved_r0 = r0();
-        pi->saved_r2 = r2();
-       
-       w2(4); w0(4); w2(6); w2(7);
-       a = r1() & 0xff; w2(4); b = r1() & 0xff;
-       w2(0xc); w2(0xe); w2(4);
-
-       pi->delay = olddelay;
-        w0(pi->saved_r0);
-        w2(pi->saved_r2);
-
-       return ((~a&0x40) && (b&0x40));
-} 
-
-/* We use the pi->private to remember the result of the PNP test.
-   To make this work, private = port*2 + chip.  Yes, I know it's
-   a hack :-(
-*/
-
-static int frpw_test_proto( PIA *pi, char * scratch, int verbose )
-
-{       int     j, k, r;
-       int     e[2] = {0,0};
-
-       if ((pi->private>>1) != pi->port)
-          pi->private = frpw_test_pnp(pi) + 2*pi->port;
-
-       if (((pi->private%2) == 0) && (pi->mode > 2)) {
-          if (verbose) 
-               printk("%s: frpw: Xilinx does not support mode %d\n",
-                       pi->device, pi->mode);
-          return 1;
-       }
-
-       if (((pi->private%2) == 1) && (pi->mode == 2)) {
-          if (verbose)
-               printk("%s: frpw: ASIC does not support mode 2\n",
-                       pi->device);
-          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);
-
-        if (verbose)  {
-            printk("%s: frpw: port 0x%x, chip %ld, mode %d, test=(%d,%d,%d)\n",
-                   pi->device,pi->port,(pi->private%2),pi->mode,e[0],e[1],r);
-        }
-
-        return (r || (e[0] && e[1]));
-}
-
-
-static void frpw_log_adapter( PIA *pi, char * scratch, int verbose )
-
-{       char    *mode_string[6] = {"4-bit","8-bit","EPP",
-                                  "EPP-8","EPP-16","EPP-32"};
-
-        printk("%s: frpw %s, Freecom (%s) adapter at 0x%x, ", pi->device,
-               FRPW_VERSION,((pi->private%2) == 0)?"Xilinx":"ASIC",pi->port);
-        printk("mode %d (%s), delay %d\n",pi->mode,
-               mode_string[pi->mode],pi->delay);
-
-}
-
-static struct pi_protocol frpw = {
-       .owner          = THIS_MODULE,
-       .name           = "frpw",
-       .max_mode       = 6,
-       .epp_first      = 2,
-       .default_delay  = 2,
-       .max_units      = 1,
-       .write_regr     = frpw_write_regr,
-       .read_regr      = frpw_read_regr,
-       .write_block    = frpw_write_block,
-       .read_block     = frpw_read_block,
-       .connect        = frpw_connect,
-       .disconnect     = frpw_disconnect,
-       .test_proto     = frpw_test_proto,
-       .log_adapter    = frpw_log_adapter,
-};
-
-static int __init frpw_init(void)
-{
-       return paride_register(&frpw);
-}
-
-static void __exit frpw_exit(void)
-{
-       paride_unregister(&frpw);
-}
-
-MODULE_LICENSE("GPL");
-module_init(frpw_init)
-module_exit(frpw_exit)
diff --git a/drivers/block/paride/kbic.c b/drivers/block/paride/kbic.c
deleted file mode 100644 (file)
index f0960eb..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
-        kbic.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                              Under the terms of the GNU General Public License.
-
-        This is a low-level driver for the KBIC-951A and KBIC-971A
-        parallel to IDE adapter chips from KingByte Information Systems.
-
-       The chips are almost identical, however, the wakeup code 
-       required for the 971A interferes with the correct operation of
-        the 951A, so this driver registers itself twice, once for
-       each chip.
-
-*/
-
-/* Changes:
-
-        1.01    GRG 1998.05.06 init_proto, release_proto
-
-*/
-
-#define KBIC_VERSION      "1.01"
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <asm/io.h>
-
-#include <linux/pata_parport.h>
-
-#define r12w()                 (delay_p,inw(pi->port+1)&0xffff) 
-
-#define j44(a,b)                ((((a>>4)&0x0f)|(b&0xf0))^0x88)
-#define j53(w)                  (((w>>3)&0x1f)|((w>>4)&0xe0))
-
-
-/* cont = 0 - access the IDE register file 
-   cont = 1 - access the IDE command set 
-*/
-
-static int  cont_map[2] = { 0x80, 0x40 };
-
-static int kbic_read_regr( PIA *pi, int cont, int regr )
-
-{       int     a, b, s;
-
-        s = cont_map[cont];
-
-       switch (pi->mode) {
-
-       case 0: w0(regr|0x18|s); w2(4); w2(6); w2(4); w2(1); w0(8);
-               a = r1(); w0(0x28); b = r1(); w2(4);
-               return j44(a,b);
-
-       case 1: w0(regr|0x38|s); w2(4); w2(6); w2(4); w2(5); w0(8);
-               a = r12w(); w2(4);
-               return j53(a);
-
-       case 2: w0(regr|0x08|s); w2(4); w2(6); w2(4); w2(0xa5); w2(0xa1);
-               a = r0(); w2(4);
-                       return a;
-
-       case 3:
-       case 4:
-       case 5: w0(0x20|s); w2(4); w2(6); w2(4); w3(regr);
-               a = r4(); b = r4(); w2(4); w2(0); w2(4);
-               return a;
-
-       }
-       return -1;
-}       
-
-static void  kbic_write_regr( PIA *pi, int cont, int regr, int val)
-
-{       int  s;
-
-        s = cont_map[cont];
-
-        switch (pi->mode) {
-
-       case 0: 
-        case 1:
-       case 2: w0(regr|0x10|s); w2(4); w2(6); w2(4); 
-               w0(val); w2(5); w2(4);
-               break;
-
-       case 3:
-       case 4:
-       case 5: w0(0x20|s); w2(4); w2(6); w2(4); w3(regr);
-               w4(val); w4(val);
-               w2(4); w2(0); w2(4);
-                break;
-
-       }
-}
-
-static void k951_connect ( PIA *pi  )
-
-{      pi->saved_r0 = r0();
-        pi->saved_r2 = r2();
-        w2(4); 
-}
-
-static void k951_disconnect ( PIA *pi )
-
-{              w0(pi->saved_r0);
-        w2(pi->saved_r2);
-}
-
-#define        CCP(x)  w2(0xc4);w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);\
-               w0(0x78);w0(x);w2(0xc5);w2(0xc4);w0(0xff);
-
-static void k971_connect ( PIA *pi  )
-
-{      pi->saved_r0 = r0();
-        pi->saved_r2 = r2();
-       CCP(0x20);
-        w2(4); 
-}
-
-static void k971_disconnect ( PIA *pi )
-
-{       CCP(0x30);
-       w0(pi->saved_r0);
-        w2(pi->saved_r2);
-}
-
-/* counts must be congruent to 0 MOD 4, but all known applications
-   have this property.
-*/
-
-static void kbic_read_block( PIA *pi, char * buf, int count )
-
-{       int     k, a, b;
-
-        switch (pi->mode) {
-
-        case 0: w0(0x98); w2(4); w2(6); w2(4);
-                for (k=0;k<count/2;k++) {
-                       w2(1); w0(8);    a = r1();
-                              w0(0x28); b = r1();
-                       buf[2*k]   = j44(a,b);
-                       w2(5);           b = r1();
-                              w0(8);    a = r1();
-                       buf[2*k+1] = j44(a,b);
-                       w2(4);
-                } 
-                break;
-
-        case 1: w0(0xb8); w2(4); w2(6); w2(4); 
-                for (k=0;k<count/4;k++) {
-                        w0(0xb8); 
-                       w2(4); w2(5); 
-                        w0(8);    buf[4*k]   = j53(r12w());
-                       w0(0xb8); buf[4*k+1] = j53(r12w());
-                       w2(4); w2(5);
-                                 buf[4*k+3] = j53(r12w());
-                       w0(8);    buf[4*k+2] = j53(r12w());
-                }
-                w2(4);
-                break;
-
-        case 2: w0(0x88); w2(4); w2(6); w2(4);
-                for (k=0;k<count/2;k++) {
-                        w2(0xa0); w2(0xa1); buf[2*k] = r0();
-                        w2(0xa5); buf[2*k+1] = r0();
-                }
-                w2(4);
-                break;
-
-        case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
-                for (k=0;k<count;k++) buf[k] = r4();
-                w2(4); w2(0); w2(4);
-                break;
-
-       case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
-                for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
-                w2(4); w2(0); w2(4);
-                break;
-
-        case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
-                for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
-                w2(4); w2(0); w2(4);
-                break;
-
-
-        }
-}
-
-static void kbic_write_block( PIA *pi, char * buf, int count )
-
-{       int     k;
-
-        switch (pi->mode) {
-
-        case 0:
-        case 1:
-        case 2: w0(0x90); w2(4); w2(6); w2(4); 
-               for(k=0;k<count/2;k++) {
-                       w0(buf[2*k+1]); w2(0); w2(4); 
-                       w0(buf[2*k]);   w2(5); w2(4); 
-               }
-               break;
-
-        case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
-               for(k=0;k<count/2;k++) {
-                       w4(buf[2*k+1]); 
-                        w4(buf[2*k]);
-                }
-               w2(4); w2(0); w2(4);
-               break;
-
-       case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
-                for(k=0;k<count/2;k++) w4w(pi_swab16(buf,k));
-                w2(4); w2(0); w2(4);
-                break;
-
-        case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
-                for(k=0;k<count/4;k++) w4l(pi_swab32(buf,k));
-                w2(4); w2(0); w2(4);
-                break;
-
-        }
-
-}
-
-static void kbic_log_adapter( PIA *pi, char * scratch, 
-                             int verbose, char * chip )
-
-{       char    *mode_string[6] = {"4-bit","5/3","8-bit",
-                                  "EPP-8","EPP_16","EPP-32"};
-
-        printk("%s: kbic %s, KingByte %s at 0x%x, ",
-                pi->device,KBIC_VERSION,chip,pi->port);
-        printk("mode %d (%s), delay %d\n",pi->mode,
-               mode_string[pi->mode],pi->delay);
-
-}
-
-static void k951_log_adapter( PIA *pi, char * scratch, int verbose )
-
-{      kbic_log_adapter(pi,scratch,verbose,"KBIC-951A");
-}
-
-static void k971_log_adapter( PIA *pi, char * scratch, int verbose )
-
-{       kbic_log_adapter(pi,scratch,verbose,"KBIC-971A");
-}
-
-static struct pi_protocol k951 = {
-       .owner          = THIS_MODULE,
-       .name           = "k951",
-       .max_mode       = 6,
-       .epp_first      = 3,
-       .default_delay  = 1,
-       .max_units      = 1,
-       .write_regr     = kbic_write_regr,
-       .read_regr      = kbic_read_regr,
-       .write_block    = kbic_write_block,
-       .read_block     = kbic_read_block,
-       .connect        = k951_connect,
-       .disconnect     = k951_disconnect,
-       .log_adapter    = k951_log_adapter,
-};
-
-static struct pi_protocol k971 = {
-       .owner          = THIS_MODULE,
-       .name           = "k971",
-       .max_mode       = 6,
-       .epp_first      = 3,
-       .default_delay  = 1,
-       .max_units      = 1,
-       .write_regr     = kbic_write_regr,
-       .read_regr      = kbic_read_regr,
-       .write_block    = kbic_write_block,
-       .read_block     = kbic_read_block,
-       .connect        = k971_connect,
-       .disconnect     = k971_disconnect,
-       .log_adapter    = k971_log_adapter,
-};
-
-static int __init kbic_init(void)
-{
-       int rv;
-
-       rv = paride_register(&k951);
-       if (rv < 0)
-               return rv;
-       rv = paride_register(&k971);
-       if (rv < 0)
-               paride_unregister(&k951);
-       return rv;
-}
-
-static void __exit kbic_exit(void)
-{
-       paride_unregister(&k951);
-       paride_unregister(&k971);
-}
-
-MODULE_LICENSE("GPL");
-module_init(kbic_init)
-module_exit(kbic_exit)
diff --git a/drivers/block/paride/ktti.c b/drivers/block/paride/ktti.c
deleted file mode 100644 (file)
index fc4f707..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/* 
-        ktti.c        (c) 1998  Grant R. Guenther <grant@torque.net>
-                          Under the terms of the GNU General Public License.
-
-       ktti.c is a low-level protocol driver for the KT Technology
-       parallel port adapter.  This adapter is used in the "PHd" 
-        portable hard-drives.  As far as I can tell, this device
-       supports 4-bit mode _only_.  
-
-*/
-
-#define KTTI_VERSION      "1.0"
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <asm/io.h>
-
-#include <linux/pata_parport.h>
-
-#define j44(a,b)                (((a>>4)&0x0f)|(b&0xf0))
-
-/* cont = 0 - access the IDE register file 
-   cont = 1 - access the IDE command set 
-*/
-
-static int  cont_map[2] = { 0x10, 0x08 };
-
-static void  ktti_write_regr( PIA *pi, int cont, int regr, int val)
-
-{      int r;
-
-       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);
-}
-
-static int ktti_read_regr( PIA *pi, int cont, int regr )
-
-{      int  a, b, r;
-
-        r = regr + cont_map[cont];
-
-        w0(r); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9); 
-       a = r1(); w2(0xc);  b = r1(); w2(9); w2(0xc); w2(9);
-       return j44(a,b);
-
-}
-
-static void ktti_read_block( PIA *pi, char * buf, int count )
-
-{      int  k, a, b;
-
-       for (k=0;k<count/2;k++) {
-               w0(0x10); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9);
-               a = r1(); w2(0xc); b = r1(); w2(9);
-               buf[2*k] = j44(a,b);
-               a = r1(); w2(0xc); b = r1(); w2(9);
-               buf[2*k+1] = j44(a,b);
-       }
-}
-
-static void ktti_write_block( PIA *pi, char * buf, int count )
-
-{      int k;
-
-       for (k=0;k<count/2;k++) {
-               w0(0x10); w2(0xb); w2(0xa); w2(3); w2(6);
-               w0(buf[2*k]); w2(3);
-               w0(buf[2*k+1]); w2(6);
-               w2(0xb);
-       }
-}
-
-static void ktti_connect ( PIA *pi  )
-
-{       pi->saved_r0 = r0();
-        pi->saved_r2 = r2();
-       w2(0xb); w2(0xa); w0(0); w2(3); w2(6);  
-}
-
-static void ktti_disconnect ( PIA *pi )
-
-{       w2(0xb); w2(0xa); w0(0xa0); w2(3); w2(4);
-       w0(pi->saved_r0);
-        w2(pi->saved_r2);
-} 
-
-static void ktti_log_adapter( PIA *pi, char * scratch, int verbose )
-
-{       printk("%s: ktti %s, KT adapter at 0x%x, delay %d\n",
-                pi->device,KTTI_VERSION,pi->port,pi->delay);
-
-}
-
-static struct pi_protocol ktti = {
-       .owner          = THIS_MODULE,
-       .name           = "ktti",
-       .max_mode       = 1,
-       .epp_first      = 2,
-       .default_delay  = 1,
-       .max_units      = 1,
-       .write_regr     = ktti_write_regr,
-       .read_regr      = ktti_read_regr,
-       .write_block    = ktti_write_block,
-       .read_block     = ktti_read_block,
-       .connect        = ktti_connect,
-       .disconnect     = ktti_disconnect,
-       .log_adapter    = ktti_log_adapter,
-};
-
-static int __init ktti_init(void)
-{
-       return paride_register(&ktti);
-}
-
-static void __exit ktti_exit(void)
-{
-       paride_unregister(&ktti);
-}
-
-MODULE_LICENSE("GPL");
-module_init(ktti_init)
-module_exit(ktti_exit)
diff --git a/drivers/block/paride/on20.c b/drivers/block/paride/on20.c
deleted file mode 100644 (file)
index 995fc41..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/* 
-       on20.c  (c) 1996-8  Grant R. Guenther <grant@torque.net>
-                           Under the terms of the GNU General Public License.
-
-        on20.c is a low-level protocol driver for the
-        Onspec 90c20 parallel to IDE adapter. 
-*/
-
-/* Changes:
-
-        1.01    GRG 1998.05.06 init_proto, release_proto
-
-*/
-
-#define        ON20_VERSION    "1.01"
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <asm/io.h>
-
-#include <linux/pata_parport.h>
-
-#define op(f)  w2(4);w0(f);w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4);
-#define vl(v)  w2(4);w0(v);w2(5);w2(7);w2(5);w2(4);
-
-#define j44(a,b)  (((a>>4)&0x0f)|(b&0xf0))
-
-/* cont = 0 - access the IDE register file 
-   cont = 1 - access the IDE command set 
-*/
-
-static int on20_read_regr( PIA *pi, int cont, int regr )
-
-{      int h,l, r ;
-
-        r = (regr<<2) + 1 + cont;
-
-        op(1); vl(r); op(0);
-
-       switch (pi->mode)  {
-
-        case 0:  w2(4); w2(6); l = r1();
-                 w2(4); w2(6); h = r1();
-                 w2(4); w2(6); w2(4); w2(6); w2(4);
-                return j44(l,h);
-
-       case 1:  w2(4); w2(0x26); r = r0(); 
-                 w2(4); w2(0x26); w2(4);
-                return r;
-
-       }
-       return -1;
-}      
-
-static void on20_write_regr( PIA *pi, int cont, int regr, int val )
-
-{      int r;
-
-       r = (regr<<2) + 1 + cont;
-
-       op(1); vl(r); 
-       op(0); vl(val); 
-       op(0); vl(val);
-}
-
-static void on20_connect ( PIA *pi)
-
-{      pi->saved_r0 = r0();
-        pi->saved_r2 = r2();
-
-       w2(4);w0(0);w2(0xc);w2(4);w2(6);w2(4);w2(6);w2(4); 
-       if (pi->mode) { op(2); vl(8); op(2); vl(9); }
-              else   { op(2); vl(0); op(2); vl(8); }
-}
-
-static void on20_disconnect ( PIA *pi )
-
-{      w2(4);w0(7);w2(4);w2(0xc);w2(4);
-        w0(pi->saved_r0);
-        w2(pi->saved_r2);
-} 
-
-static void on20_read_block( PIA *pi, char * buf, int count )
-
-{      int     k, l, h; 
-
-       op(1); vl(1); op(0);
-
-       for (k=0;k<count;k++) 
-           if (pi->mode) {
-               w2(4); w2(0x26); buf[k] = r0();
-           } else {
-               w2(6); l = r1(); w2(4);
-               w2(6); h = r1(); w2(4);
-               buf[k] = j44(l,h);
-           }
-       w2(4);
-}
-
-static void on20_write_block(  PIA *pi, char * buf, int count )
-
-{      int     k;
-
-       op(1); vl(1); op(0);
-
-       for (k=0;k<count;k++) { w2(5); w0(buf[k]); w2(7); }
-       w2(4);
-}
-
-static void on20_log_adapter( PIA *pi, char * scratch, int verbose )
-
-{       char    *mode_string[2] = {"4-bit","8-bit"};
-
-        printk("%s: on20 %s, OnSpec 90c20 at 0x%x, ",
-                pi->device,ON20_VERSION,pi->port);
-        printk("mode %d (%s), delay %d\n",pi->mode,
-               mode_string[pi->mode],pi->delay);
-
-}
-
-static struct pi_protocol on20 = {
-       .owner          = THIS_MODULE,
-       .name           = "on20",
-       .max_mode       = 2,
-       .epp_first      = 2,
-       .default_delay  = 1,
-       .max_units      = 1,
-       .write_regr     = on20_write_regr,
-       .read_regr      = on20_read_regr,
-       .write_block    = on20_write_block,
-       .read_block     = on20_read_block,
-       .connect        = on20_connect,
-       .disconnect     = on20_disconnect,
-       .log_adapter    = on20_log_adapter,
-};
-
-static int __init on20_init(void)
-{
-       return paride_register(&on20);
-}
-
-static void __exit on20_exit(void)
-{
-       paride_unregister(&on20);
-}
-
-MODULE_LICENSE("GPL");
-module_init(on20_init)
-module_exit(on20_exit)
diff --git a/drivers/block/paride/on26.c b/drivers/block/paride/on26.c
deleted file mode 100644 (file)
index 35f1c48..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-/* 
-        on26.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
-                              Under the terms of the GNU General Public License.
-
-        on26.c is a low-level protocol driver for the 
-        OnSpec 90c26 parallel to IDE adapter chip.
-
-*/
-
-/* Changes:
-
-        1.01    GRG 1998.05.06 init_proto, release_proto
-       1.02    GRG 1998.09.23 updates for the -E rev chip
-       1.03    GRG 1998.12.14 fix for slave drives
-       1.04    GRG 1998.12.20 yet another bug fix
-
-*/
-
-#define ON26_VERSION      "1.04"
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <asm/io.h>
-
-#include <linux/pata_parport.h>
-
-/* mode codes:  0  nybble reads, 8-bit writes
-                1  8-bit reads and writes
-                2  8-bit EPP mode
-               3  EPP-16
-               4  EPP-32
-*/
-
-#define j44(a,b)  (((a>>4)&0x0f)|(b&0xf0))
-
-#define P1     w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4);
-#define P2     w2(5);w2(7);w2(5);w2(4);
-
-/* cont = 0 - access the IDE register file 
-   cont = 1 - access the IDE command set 
-*/
-
-static int on26_read_regr( PIA *pi, int cont, int regr )
-
-{       int     a, b, r;
-
-       r = (regr<<2) + 1 + cont;
-
-        switch (pi->mode)  {
-
-        case 0: w0(1); P1; w0(r); P2; w0(0); P1; 
-               w2(6); a = r1(); w2(4);
-               w2(6); b = r1(); w2(4);
-               w2(6); w2(4); w2(6); w2(4);
-                return j44(a,b);
-
-        case 1: w0(1); P1; w0(r); P2; w0(0); P1;
-               w2(0x26); a = r0(); w2(4); w2(0x26); w2(4);
-                return a;
-
-       case 2:
-       case 3:
-        case 4: w3(1); w3(1); w2(5); w4(r); w2(4);
-               w3(0); w3(0); w2(0x24); a = r4(); w2(4);
-               w2(0x24); (void)r4(); w2(4);
-                return a;
-
-        }
-        return -1;
-}       
-
-static void on26_write_regr( PIA *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);\
-                w0(0x87);w0(0x78);w0(x);w2(4);w2(5);w2(4);w0(0xff);
-
-static void on26_connect ( PIA *pi )
-
-{       int    x;
-
-       pi->saved_r0 = r0();
-        pi->saved_r2 = r2();
-
-        CCP(0x20);
-       x = 8; if (pi->mode) x = 9;
-
-       w0(2); P1; w0(8); P2;
-       w0(2); P1; w0(x); P2;
-}
-
-static void on26_disconnect ( PIA *pi )
-
-{       if (pi->mode >= 2) { w3(4); w3(4); w3(4); w3(4); }
-                     else { w0(4); P1; w0(4); P1; }
-       CCP(0x30);
-        w0(pi->saved_r0);
-        w2(pi->saved_r2);
-} 
-
-#define        RESET_WAIT  200
-
-static int on26_test_port( PIA *pi)  /* hard reset */
-
-{       int     i, m, d, x=0, y=0;
-
-        pi->saved_r0 = r0();
-        pi->saved_r2 = r2();
-
-        d = pi->delay;
-        m = pi->mode;
-        pi->delay = 5;
-        pi->mode = 0;
-
-        w2(0xc);
-
-        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);
-
-        if (i == 0xb5f) {
-
-            w0(2); P1; w0(0);   P2;
-            w0(3); P1; w0(0);   P2;
-            w0(2); P1; w0(8);   P2; udelay(100);
-            w0(2); P1; w0(0xa); P2; udelay(100);
-            w0(2); P1; w0(8);   P2; udelay(1000);
-            
-            on26_write_regr(pi,0,6,0xa0);
-
-            for (i=0;i<RESET_WAIT;i++) {
-                on26_write_regr(pi,0,6,0xa0);
-                x = on26_read_regr(pi,0,7);
-                on26_write_regr(pi,0,6,0xb0);
-                y = on26_read_regr(pi,0,7);
-                if (!((x&0x80)||(y&0x80))) break;
-                mdelay(100);
-            }
-
-           if (i == RESET_WAIT) 
-               printk("on26: Device reset failed (%x,%x)\n",x,y);
-
-            w0(4); P1; w0(4); P1;
-        }
-
-        CCP(0x30);
-
-        pi->delay = d;
-        pi->mode = m;
-        w0(pi->saved_r0);
-        w2(pi->saved_r2);
-
-        return 5;
-}
-
-
-static void on26_read_block( PIA *pi, char * buf, int count )
-
-{       int     k, a, b;
-
-        switch (pi->mode) {
-
-        case 0: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x18); P2; w0(0); P1;
-               udelay(10);
-               for (k=0;k<count;k++) {
-                        w2(6); a = r1();
-                        w2(4); b = r1();
-                        buf[k] = j44(a,b);
-                }
-               w0(2); P1; w0(8); P2; 
-                break;
-
-        case 1: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x19); P2; w0(0); P1;
-               udelay(10);
-                for (k=0;k<count/2;k++) {
-                        w2(0x26); buf[2*k] = r0();  
-                       w2(0x24); buf[2*k+1] = r0();
-                }
-                w0(2); P1; w0(9); P2;
-                break;
-
-        case 2: w3(1); w3(1); w2(5); w4(1); w2(4);
-               w3(0); w3(0); w2(0x24);
-               udelay(10);
-                for (k=0;k<count;k++) buf[k] = r4();
-                w2(4);
-                break;
-
-        case 3: w3(1); w3(1); w2(5); w4(1); w2(4);
-                w3(0); w3(0); w2(0x24);
-                udelay(10);
-                for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
-                w2(4);
-                break;
-
-        case 4: w3(1); w3(1); w2(5); w4(1); w2(4);
-                w3(0); w3(0); w2(0x24);
-                udelay(10);
-                for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
-                w2(4);
-                break;
-
-        }
-}
-
-static void on26_write_block( PIA *pi, char * buf, int count )
-
-{       int    k;
-
-        switch (pi->mode) {
-
-        case 0: 
-        case 1: w0(1); P1; w0(1); P2; 
-               w0(2); P1; w0(0x18+pi->mode); P2; w0(0); P1;
-               udelay(10);
-               for (k=0;k<count/2;k++) {
-                        w2(5); w0(buf[2*k]); 
-                       w2(7); w0(buf[2*k+1]);
-                }
-                w2(5); w2(4);
-               w0(2); P1; w0(8+pi->mode); P2;
-                break;
-
-        case 2: w3(1); w3(1); w2(5); w4(1); w2(4);
-               w3(0); w3(0); w2(0xc5);
-               udelay(10);
-                for (k=0;k<count;k++) w4(buf[k]);
-               w2(0xc4);
-                break;
-
-        case 3: w3(1); w3(1); w2(5); w4(1); w2(4);
-                w3(0); w3(0); w2(0xc5);
-                udelay(10);
-                for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
-                w2(0xc4);
-                break;
-
-        case 4: w3(1); w3(1); w2(5); w4(1); w2(4);
-                w3(0); w3(0); w2(0xc5);
-                udelay(10);
-                for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
-                w2(0xc4);
-                break;
-
-        }
-
-}
-
-static void on26_log_adapter( PIA *pi, char * scratch, int verbose )
-
-{       char    *mode_string[5] = {"4-bit","8-bit","EPP-8",
-                                  "EPP-16","EPP-32"};
-
-        printk("%s: on26 %s, OnSpec 90c26 at 0x%x, ",
-                pi->device,ON26_VERSION,pi->port);
-        printk("mode %d (%s), delay %d\n",pi->mode,
-               mode_string[pi->mode],pi->delay);
-
-}
-
-static struct pi_protocol on26 = {
-       .owner          = THIS_MODULE,
-       .name           = "on26",
-       .max_mode       = 5,
-       .epp_first      = 2,
-       .default_delay  = 1,
-       .max_units      = 1,
-       .write_regr     = on26_write_regr,
-       .read_regr      = on26_read_regr,
-       .write_block    = on26_write_block,
-       .read_block     = on26_read_block,
-       .connect        = on26_connect,
-       .disconnect     = on26_disconnect,
-       .test_port      = on26_test_port,
-       .log_adapter    = on26_log_adapter,
-};
-
-static int __init on26_init(void)
-{
-       return paride_register(&on26);
-}
-
-static void __exit on26_exit(void)
-{
-       paride_unregister(&on26);
-}
-
-MODULE_LICENSE("GPL");
-module_init(on26_init)
-module_exit(on26_exit)
diff --git a/drivers/block/paride/ppc6lnx.c b/drivers/block/paride/ppc6lnx.c
deleted file mode 100644 (file)
index 5e5521d..0000000
+++ /dev/null
@@ -1,726 +0,0 @@
-/*
-       ppc6lnx.c (c) 2001 Micro Solutions Inc.
-               Released under the terms of the GNU General Public license
-
-       ppc6lnx.c  is a par of the protocol driver for the Micro Solutions
-               "BACKPACK" parallel port IDE adapter
-               (Works on Series 6 drives)
-
-*/
-
-//***************************************************************************
-
-// PPC 6 Code in C sanitized for LINUX
-// Original x86 ASM by Ron, Converted to C by Clive
-
-//***************************************************************************
-
-
-#define port_stb                                       1
-#define port_afd                                       2
-#define cmd_stb                                                port_afd
-#define port_init                                      4
-#define data_stb                                       port_init
-#define port_sel                                       8
-#define port_int                                       16
-#define port_dir                                       0x20
-
-#define ECR_EPP        0x80
-#define ECR_BI 0x20
-
-//***************************************************************************
-
-//  60772 Commands
-
-#define ACCESS_REG                             0x00
-#define ACCESS_PORT                            0x40
-
-#define ACCESS_READ                            0x00
-#define ACCESS_WRITE                   0x20
-
-//  60772 Command Prefix
-
-#define CMD_PREFIX_SET         0xe0            // Special command that modifies the next command's operation
-#define CMD_PREFIX_RESET       0xc0            // Resets current cmd modifier reg bits
- #define PREFIX_IO16                   0x01            // perform 16-bit wide I/O
- #define PREFIX_FASTWR         0x04            // enable PPC mode fast-write
- #define PREFIX_BLK                            0x08            // enable block transfer mode
-
-// 60772 Registers
-
-#define REG_STATUS                             0x00            // status register
- #define STATUS_IRQA                   0x01            // Peripheral IRQA line
- #define STATUS_EEPROM_DO      0x40            // Serial EEPROM data bit
-#define REG_VERSION                            0x01            // PPC version register (read)
-#define REG_HWCFG                                      0x02            // Hardware Config register
-#define REG_RAMSIZE                            0x03            // Size of RAM Buffer
- #define RAMSIZE_128K                  0x02
-#define REG_EEPROM                             0x06            // EEPROM control register
- #define EEPROM_SK                             0x01            // eeprom SK bit
- #define EEPROM_DI                             0x02            // eeprom DI bit
- #define EEPROM_CS                             0x04            // eeprom CS bit
- #define EEPROM_EN                             0x08            // eeprom output enable
-#define REG_BLKSIZE                            0x08            // Block transfer len (24 bit)
-
-//***************************************************************************
-
-typedef struct ppc_storage {
-       u16     lpt_addr;                               // LPT base address
-       u8      ppc_id;
-       u8      mode;                                           // operating mode
-                                       // 0 = PPC Uni SW
-                                       // 1 = PPC Uni FW
-                                       // 2 = PPC Bi SW
-                                       // 3 = PPC Bi FW
-                                       // 4 = EPP Byte
-                                       // 5 = EPP Word
-                                       // 6 = EPP Dword
-       u8      ppc_flags;
-       u8      org_data;                               // original LPT data port contents
-       u8      org_ctrl;                               // original LPT control port contents
-       u8      cur_ctrl;                               // current control port contents
-} Interface;
-
-//***************************************************************************
-
-// ppc_flags
-
-#define fifo_wait                                      0x10
-
-//***************************************************************************
-
-// DONT CHANGE THESE LEST YOU BREAK EVERYTHING - BIT FIELD DEPENDENCIES
-
-#define PPCMODE_UNI_SW         0
-#define PPCMODE_UNI_FW         1
-#define PPCMODE_BI_SW                  2
-#define PPCMODE_BI_FW                  3
-#define PPCMODE_EPP_BYTE       4
-#define PPCMODE_EPP_WORD       5
-#define PPCMODE_EPP_DWORD      6
-
-//***************************************************************************
-
-static int ppc6_select(Interface *ppc);
-static void ppc6_deselect(Interface *ppc);
-static void ppc6_send_cmd(Interface *ppc, u8 cmd);
-static void ppc6_wr_data_byte(Interface *ppc, u8 data);
-static u8 ppc6_rd_data_byte(Interface *ppc);
-static u8 ppc6_rd_port(Interface *ppc, u8 port);
-static void ppc6_wr_port(Interface *ppc, u8 port, u8 data);
-static void ppc6_rd_data_blk(Interface *ppc, u8 *data, long count);
-static void ppc6_wait_for_fifo(Interface *ppc);
-static void ppc6_wr_data_blk(Interface *ppc, u8 *data, long count);
-static void ppc6_rd_port16_blk(Interface *ppc, u8 port, u8 *data, long length);
-static void ppc6_wr_port16_blk(Interface *ppc, u8 port, u8 *data, long length);
-static void ppc6_wr_extout(Interface *ppc, u8 regdata);
-static int ppc6_open(Interface *ppc);
-static void ppc6_close(Interface *ppc);
-
-//***************************************************************************
-
-static int ppc6_select(Interface *ppc)
-{
-       u8 i, j, k;
-
-       i = inb(ppc->lpt_addr + 1);
-
-       if (i & 1)
-               outb(i, ppc->lpt_addr + 1);
-
-       ppc->org_data = inb(ppc->lpt_addr);
-
-       ppc->org_ctrl = inb(ppc->lpt_addr + 2) & 0x5F; // readback ctrl
-
-       ppc->cur_ctrl = ppc->org_ctrl;
-
-       ppc->cur_ctrl |= port_sel;
-
-       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-       if (ppc->org_data == 'b')
-               outb('x', ppc->lpt_addr);
-
-       outb('b', ppc->lpt_addr);
-       outb('p', ppc->lpt_addr);
-       outb(ppc->ppc_id, ppc->lpt_addr);
-       outb(~ppc->ppc_id,ppc->lpt_addr);
-
-       ppc->cur_ctrl &= ~port_sel;
-
-       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-       ppc->cur_ctrl = (ppc->cur_ctrl & port_int) | port_init;
-
-       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-       i = ppc->mode & 0x0C;
-
-       if (i == 0)
-               i = (ppc->mode & 2) | 1;
-
-       outb(i, ppc->lpt_addr);
-
-       ppc->cur_ctrl |= port_sel;
-
-       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-       // DELAY
-
-       ppc->cur_ctrl |= port_afd;
-
-       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-       j = ((i & 0x08) << 4) | ((i & 0x07) << 3);
-
-       k = inb(ppc->lpt_addr + 1) & 0xB8;
-
-       if (j == k)
-       {
-               ppc->cur_ctrl &= ~port_afd;
-
-               outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-               k = (inb(ppc->lpt_addr + 1) & 0xB8) ^ 0xB8;
-
-               if (j == k)
-               {
-                       if (i & 4)      // EPP
-                               ppc->cur_ctrl &= ~(port_sel | port_init);
-                       else                            // PPC/ECP
-                               ppc->cur_ctrl &= ~port_sel;
-
-                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                       return(1);
-               }
-       }
-
-       outb(ppc->org_ctrl, ppc->lpt_addr + 2);
-
-       outb(ppc->org_data, ppc->lpt_addr);
-
-       return(0); // FAIL
-}
-
-//***************************************************************************
-
-static void ppc6_deselect(Interface *ppc)
-{
-       if (ppc->mode & 4)      // EPP
-               ppc->cur_ctrl |= port_init;
-       else                                                            // PPC/ECP
-               ppc->cur_ctrl |= port_sel;
-
-       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-       outb(ppc->org_data, ppc->lpt_addr);
-
-       outb((ppc->org_ctrl | port_sel), ppc->lpt_addr + 2);
-
-       outb(ppc->org_ctrl, ppc->lpt_addr + 2);
-}
-
-//***************************************************************************
-
-static void ppc6_send_cmd(Interface *ppc, u8 cmd)
-{
-       switch(ppc->mode)
-       {
-               case PPCMODE_UNI_SW :
-               case PPCMODE_UNI_FW :
-               case PPCMODE_BI_SW :
-               case PPCMODE_BI_FW :
-               {
-                       outb(cmd, ppc->lpt_addr);
-
-                       ppc->cur_ctrl ^= cmd_stb;
-
-                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                       break;
-               }
-
-               case PPCMODE_EPP_BYTE :
-               case PPCMODE_EPP_WORD :
-               case PPCMODE_EPP_DWORD :
-               {
-                       outb(cmd, ppc->lpt_addr + 3);
-
-                       break;
-               }
-       }
-}
-
-//***************************************************************************
-
-static void ppc6_wr_data_byte(Interface *ppc, u8 data)
-{
-       switch(ppc->mode)
-       {
-               case PPCMODE_UNI_SW :
-               case PPCMODE_UNI_FW :
-               case PPCMODE_BI_SW :
-               case PPCMODE_BI_FW :
-               {
-                       outb(data, ppc->lpt_addr);
-
-                       ppc->cur_ctrl ^= data_stb;
-
-                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                       break;
-               }
-
-               case PPCMODE_EPP_BYTE :
-               case PPCMODE_EPP_WORD :
-               case PPCMODE_EPP_DWORD :
-               {
-                       outb(data, ppc->lpt_addr + 4);
-
-                       break;
-               }
-       }
-}
-
-//***************************************************************************
-
-static u8 ppc6_rd_data_byte(Interface *ppc)
-{
-       u8 data = 0;
-
-       switch(ppc->mode)
-       {
-               case PPCMODE_UNI_SW :
-               case PPCMODE_UNI_FW :
-               {
-                       ppc->cur_ctrl = (ppc->cur_ctrl & ~port_stb) ^ data_stb;
-
-                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                       // DELAY
-
-                       data = inb(ppc->lpt_addr + 1);
-
-                       data = ((data & 0x80) >> 1) | ((data & 0x38) >> 3);
-
-                       ppc->cur_ctrl |= port_stb;
-
-                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                       // DELAY
-
-                       data |= inb(ppc->lpt_addr + 1) & 0xB8;
-
-                       break;
-               }
-
-               case PPCMODE_BI_SW :
-               case PPCMODE_BI_FW :
-               {
-                       ppc->cur_ctrl |= port_dir;
-
-                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                       ppc->cur_ctrl = (ppc->cur_ctrl | port_stb) ^ data_stb;
-
-                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                       data = inb(ppc->lpt_addr);
-
-                       ppc->cur_ctrl &= ~port_stb;
-
-                       outb(ppc->cur_ctrl,ppc->lpt_addr + 2);
-
-                       ppc->cur_ctrl &= ~port_dir;
-
-                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                       break;
-               }
-
-               case PPCMODE_EPP_BYTE :
-               case PPCMODE_EPP_WORD :
-               case PPCMODE_EPP_DWORD :
-               {
-                       outb((ppc->cur_ctrl | port_dir),ppc->lpt_addr + 2);
-
-                       data = inb(ppc->lpt_addr + 4);
-
-                       outb(ppc->cur_ctrl,ppc->lpt_addr + 2);
-
-                       break;
-               }
-       }
-
-       return(data);
-}
-
-//***************************************************************************
-
-static u8 ppc6_rd_port(Interface *ppc, u8 port)
-{
-       ppc6_send_cmd(ppc,(u8)(port | ACCESS_PORT | ACCESS_READ));
-
-       return(ppc6_rd_data_byte(ppc));
-}
-
-//***************************************************************************
-
-static void ppc6_wr_port(Interface *ppc, u8 port, u8 data)
-{
-       ppc6_send_cmd(ppc,(u8)(port | ACCESS_PORT | ACCESS_WRITE));
-
-       ppc6_wr_data_byte(ppc, data);
-}
-
-//***************************************************************************
-
-static void ppc6_rd_data_blk(Interface *ppc, u8 *data, long count)
-{
-       switch(ppc->mode)
-       {
-               case PPCMODE_UNI_SW :
-               case PPCMODE_UNI_FW :
-               {
-                       while(count)
-                       {
-                               u8 d;
-
-                               ppc->cur_ctrl = (ppc->cur_ctrl & ~port_stb) ^ data_stb;
-
-                               outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                               // DELAY
-
-                               d = inb(ppc->lpt_addr + 1);
-
-                               d = ((d & 0x80) >> 1) | ((d & 0x38) >> 3);
-
-                               ppc->cur_ctrl |= port_stb;
-
-                               outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                               // DELAY
-
-                               d |= inb(ppc->lpt_addr + 1) & 0xB8;
-
-                               *data++ = d;
-                               count--;
-                       }
-
-                       break;
-               }
-
-               case PPCMODE_BI_SW :
-               case PPCMODE_BI_FW :
-               {
-                       ppc->cur_ctrl |= port_dir;
-
-                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                       ppc->cur_ctrl |= port_stb;
-
-                       while(count)
-                       {
-                               ppc->cur_ctrl ^= data_stb;
-
-                               outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                               *data++ = inb(ppc->lpt_addr);
-                               count--;
-                       }
-
-                       ppc->cur_ctrl &= ~port_stb;
-
-                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                       ppc->cur_ctrl &= ~port_dir;
-
-                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                       break;
-               }
-
-               case PPCMODE_EPP_BYTE :
-               {
-                       outb((ppc->cur_ctrl | port_dir), ppc->lpt_addr + 2);
-
-                       // DELAY
-
-                       while(count)
-                       {
-                               *data++ = inb(ppc->lpt_addr + 4);
-                               count--;
-                       }
-
-                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                       break;
-               }
-
-               case PPCMODE_EPP_WORD :
-               {
-                       outb((ppc->cur_ctrl | port_dir), ppc->lpt_addr + 2);
-
-                       // DELAY
-
-                       while(count > 1)
-                       {
-                               *((u16 *)data) = inw(ppc->lpt_addr + 4);
-                               data  += 2;
-                               count -= 2;
-                       }
-
-                       while(count)
-                       {
-                               *data++ = inb(ppc->lpt_addr + 4);
-                               count--;
-                       }
-
-                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                       break;
-               }
-
-               case PPCMODE_EPP_DWORD :
-               {
-                       outb((ppc->cur_ctrl | port_dir),ppc->lpt_addr + 2);
-
-                       // DELAY
-
-                       while(count > 3)
-                       {
-                               *((u32 *)data) = inl(ppc->lpt_addr + 4);
-                               data  += 4;
-                               count -= 4;
-                       }
-
-                       while(count)
-                       {
-                               *data++ = inb(ppc->lpt_addr + 4);
-                               count--;
-                       }
-
-                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                       break;
-               }
-       }
-
-}
-
-//***************************************************************************
-
-static void ppc6_wait_for_fifo(Interface *ppc)
-{
-       int i;
-
-       if (ppc->ppc_flags & fifo_wait)
-       {
-               for(i=0; i<20; i++)
-                       inb(ppc->lpt_addr + 1);
-       }
-}
-
-//***************************************************************************
-
-static void ppc6_wr_data_blk(Interface *ppc, u8 *data, long count)
-{
-       switch(ppc->mode)
-       {
-               case PPCMODE_UNI_SW :
-               case PPCMODE_BI_SW :
-               {
-                       while(count--)
-                       {
-                               outb(*data++, ppc->lpt_addr);
-
-                               ppc->cur_ctrl ^= data_stb;
-
-                               outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-                       }
-
-                       break;
-               }
-
-               case PPCMODE_UNI_FW :
-               case PPCMODE_BI_FW :
-               {
-                       u8 this, last;
-
-                       ppc6_send_cmd(ppc,(CMD_PREFIX_SET | PREFIX_FASTWR));
-
-                       ppc->cur_ctrl |= port_stb;
-
-                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                       last = *data;
-
-                       outb(last, ppc->lpt_addr);
-
-                       while(count)
-                       {
-                               this = *data++;
-                               count--;
-
-                               if (this == last)
-                               {
-                                       ppc->cur_ctrl ^= data_stb;
-
-                                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-                               }
-                               else
-                               {
-                                       outb(this, ppc->lpt_addr);
-
-                                       last = this;
-                               }
-                       }
-
-                       ppc->cur_ctrl &= ~port_stb;
-
-                       outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
-
-                       ppc6_send_cmd(ppc,(CMD_PREFIX_RESET | PREFIX_FASTWR));
-
-                       break;
-               }
-
-               case PPCMODE_EPP_BYTE :
-               {
-                       while(count)
-                       {
-                               outb(*data++,ppc->lpt_addr + 4);
-                               count--;
-                       }
-
-                       ppc6_wait_for_fifo(ppc);
-
-                       break;
-               }
-
-               case PPCMODE_EPP_WORD :
-               {
-                       while(count > 1)
-                       {
-                               outw(*((u16 *)data),ppc->lpt_addr + 4);
-                               data  += 2;
-                               count -= 2;
-                       }
-
-                       while(count)
-                       {
-                               outb(*data++,ppc->lpt_addr + 4);
-                               count--;
-                       }
-
-                       ppc6_wait_for_fifo(ppc);
-
-                       break;
-               }
-
-               case PPCMODE_EPP_DWORD :
-               {
-                       while(count > 3)
-                       {
-                               outl(*((u32 *)data),ppc->lpt_addr + 4);
-                               data  += 4;
-                               count -= 4;
-                       }
-
-                       while(count)
-                       {
-                               outb(*data++,ppc->lpt_addr + 4);
-                               count--;
-                       }
-
-                       ppc6_wait_for_fifo(ppc);
-
-                       break;
-               }
-       }
-}
-
-//***************************************************************************
-
-static void ppc6_rd_port16_blk(Interface *ppc, u8 port, u8 *data, long length)
-{
-       length = length << 1;
-
-       ppc6_send_cmd(ppc, (REG_BLKSIZE | ACCESS_REG | ACCESS_WRITE));
-       ppc6_wr_data_byte(ppc,(u8)length);
-       ppc6_wr_data_byte(ppc,(u8)(length >> 8));
-       ppc6_wr_data_byte(ppc,0);
-
-       ppc6_send_cmd(ppc, (CMD_PREFIX_SET | PREFIX_IO16 | PREFIX_BLK));
-
-       ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_READ));
-
-       ppc6_rd_data_blk(ppc, data, length);
-
-       ppc6_send_cmd(ppc, (CMD_PREFIX_RESET | PREFIX_IO16 | PREFIX_BLK));
-}
-
-//***************************************************************************
-
-static void ppc6_wr_port16_blk(Interface *ppc, u8 port, u8 *data, long length)
-{
-       length = length << 1;
-
-       ppc6_send_cmd(ppc, (REG_BLKSIZE | ACCESS_REG | ACCESS_WRITE));
-       ppc6_wr_data_byte(ppc,(u8)length);
-       ppc6_wr_data_byte(ppc,(u8)(length >> 8));
-       ppc6_wr_data_byte(ppc,0);
-
-       ppc6_send_cmd(ppc, (CMD_PREFIX_SET | PREFIX_IO16 | PREFIX_BLK));
-
-       ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_WRITE));
-
-       ppc6_wr_data_blk(ppc, data, length);
-
-       ppc6_send_cmd(ppc, (CMD_PREFIX_RESET | PREFIX_IO16 | PREFIX_BLK));
-}
-
-//***************************************************************************
-
-static void ppc6_wr_extout(Interface *ppc, u8 regdata)
-{
-       ppc6_send_cmd(ppc,(REG_VERSION | ACCESS_REG | ACCESS_WRITE));
-
-       ppc6_wr_data_byte(ppc, (u8)((regdata & 0x03) << 6));
-}
-
-//***************************************************************************
-
-static int ppc6_open(Interface *ppc)
-{
-       int ret;
-
-       ret = ppc6_select(ppc);
-
-       if (ret == 0)
-               return(ret);
-
-       ppc->ppc_flags &= ~fifo_wait;
-
-       ppc6_send_cmd(ppc, (ACCESS_REG | ACCESS_WRITE | REG_RAMSIZE));
-       ppc6_wr_data_byte(ppc, RAMSIZE_128K);
-
-       ppc6_send_cmd(ppc, (ACCESS_REG | ACCESS_READ | REG_VERSION));
-
-       if ((ppc6_rd_data_byte(ppc) & 0x3F) == 0x0C)
-               ppc->ppc_flags |= fifo_wait;
-
-       return(ret);
-}
-
-//***************************************************************************
-
-static void ppc6_close(Interface *ppc)
-{
-       ppc6_deselect(ppc);
-}
-
-//***************************************************************************
-