summaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_parport/bpck6.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/pata_parport/bpck6.c')
-rw-r--r--drivers/ata/pata_parport/bpck6.c68
1 files changed, 55 insertions, 13 deletions
diff --git a/drivers/ata/pata_parport/bpck6.c b/drivers/ata/pata_parport/bpck6.c
index 02f16dedfd29..9b05e1c827cd 100644
--- a/drivers/ata/pata_parport/bpck6.c
+++ b/drivers/ata/pata_parport/bpck6.c
@@ -176,21 +176,63 @@ static void bpck6_read_block(struct pi_adapter *pi, char *buf, int len)
static int bpck6_open(struct pi_adapter *pi)
{
- int ret = ppc6_select(pi);
-
- if (ret == 0)
- return ret;
-
- pi->private = 0;
-
- ppc6_send_cmd(pi, ACCESS_REG | ACCESS_WRITE | REG_RAMSIZE);
- ppc6_wr_data_byte(pi, RAMSIZE_128K);
+ u8 i, j, k;
+
+ pi->saved_r0 = parport_read_data(pi->pardev->port);
+ pi->saved_r2 = parport_read_control(pi->pardev->port) & 0x5F;
+
+ parport_frob_control(pi->pardev->port, PARPORT_CONTROL_SELECT,
+ PARPORT_CONTROL_SELECT);
+ if (pi->saved_r0 == 'b')
+ parport_write_data(pi->pardev->port, 'x');
+ parport_write_data(pi->pardev->port, 'b');
+ parport_write_data(pi->pardev->port, 'p');
+ parport_write_data(pi->pardev->port, pi->unit);
+ parport_write_data(pi->pardev->port, ~pi->unit);
+
+ parport_frob_control(pi->pardev->port, PARPORT_CONTROL_SELECT, 0);
+ parport_write_control(pi->pardev->port, PARPORT_CONTROL_INIT);
+
+ i = mode_map[pi->mode] & 0x0C;
+ if (i == 0)
+ i = (mode_map[pi->mode] & 2) | 1;
+ parport_write_data(pi->pardev->port, i);
+
+ parport_frob_control(pi->pardev->port, PARPORT_CONTROL_SELECT,
+ PARPORT_CONTROL_SELECT);
+ parport_frob_control(pi->pardev->port, PARPORT_CONTROL_AUTOFD,
+ PARPORT_CONTROL_AUTOFD);
+
+ j = ((i & 0x08) << 4) | ((i & 0x07) << 3);
+ k = parport_read_status(pi->pardev->port) & 0xB8;
+ if (j == k) {
+ parport_frob_control(pi->pardev->port, PARPORT_CONTROL_AUTOFD, 0);
+ k = (parport_read_status(pi->pardev->port) & 0xB8) ^ 0xB8;
+ if (j == k) {
+ if (i & 4) // EPP
+ parport_frob_control(pi->pardev->port,
+ PARPORT_CONTROL_SELECT | PARPORT_CONTROL_INIT, 0);
+ else // PPC/ECP
+ parport_frob_control(pi->pardev->port,
+ PARPORT_CONTROL_SELECT, 0);
+
+ pi->private = 0;
+
+ ppc6_send_cmd(pi, ACCESS_REG | ACCESS_WRITE | REG_RAMSIZE);
+ ppc6_wr_data_byte(pi, RAMSIZE_128K);
+
+ ppc6_send_cmd(pi, ACCESS_REG | ACCESS_READ | REG_VERSION);
+ if ((ppc6_rd_data_byte(pi) & 0x3F) == 0x0C)
+ pi->private |= fifo_wait;
+
+ return 1;
+ }
+ }
- ppc6_send_cmd(pi, ACCESS_REG | ACCESS_READ | REG_VERSION);
- if ((ppc6_rd_data_byte(pi) & 0x3F) == 0x0C)
- pi->private |= fifo_wait;
+ parport_write_control(pi->pardev->port, pi->saved_r2);
+ parport_write_data(pi->pardev->port, pi->saved_r0);
- return ret;
+ return 0; // FAIL
}
static void bpck6_wr_extout(struct pi_adapter *pi, u8 regdata)