static DEFINE_SPINLOCK(opti621_lock);
-/* there are stored pio numbers from other calls of opti621_set_pio_mode */
-static void compute_pios(ide_drive_t *drive, const u8 pio)
-/* Store values into drive->drive_data
- * second_contr - 0 for primary controller, 1 for secondary
- * slave_drive - 0 -> pio is for master, 1 -> pio is for slave
- * pio - PIO mode for selected drive (for other we don't know)
- */
-{
- int d;
- ide_hwif_t *hwif = HWIF(drive);
-
- drive->drive_data = pio;
-
- for (d = 0; d < 2; ++d) {
- drive = &hwif->drives[d];
- if (drive->present) {
- if (drive->drive_data == PIO_DONT_KNOW)
- drive->drive_data = ide_get_best_pio_mode(drive, 255, 3);
-#ifdef OPTI621_DEBUG
- printk("%s: Selected PIO mode %d\n",
- drive->name, drive->drive_data);
-#endif
- } else {
- drive->drive_data = PIO_NOT_EXIST;
- }
- }
-}
-
static int cmpt_clk(int time, int bus_speed)
/* Returns (rounded up) time in clocks for time in ns,
* with bus_speed in MHz.
static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- /* primary and secondary drives share some registers,
- * so we have to program both drives
- */
+ ide_hwif_t *hwif = drive->hwif;
+ ide_drive_t *pair = ide_get_paired_drive(drive);
unsigned long flags;
- u8 pio1 = 0, pio2 = 0;
pio_clocks_t first, second;
int ax, drdy;
- u8 cycle1, cycle2, misc, clk;
- ide_hwif_t *hwif = HWIF(drive);
+ u8 cycle1, misc, clk, addr_pio = pio;
- /* sets drive->drive_data for both drives */
- compute_pios(drive, pio);
- pio1 = hwif->drives[0].drive_data;
- pio2 = hwif->drives[1].drive_data;
+ drive->drive_data = XFER_PIO_0 + pio;
+
+ if (pair->present) {
+ if (pair->drive_data && pair->drive_data < drive->drive_data)
+ addr_pio = pair->drive_data - XFER_PIO_0;
+ }
spin_lock_irqsave(&opti621_lock, flags);
printk(KERN_INFO "%s: CLK = %d MHz\n", hwif->name, clk ? 25 : 33);
- compute_clocks(pio1, &first, clk ? 25 : 33);
- compute_clocks(pio2, &second, clk ? 25 : 33);
+ compute_clocks(pio, &first, clk ? 25 : 33);
+ compute_clocks(addr_pio, &second, clk ? 25 : 33);
/* ax = max(a1,a2) */
ax = (first.address_time < second.address_time) ? second.address_time : first.address_time;
drdy = 2; /* DRDY is default 2 (by OPTi Databook) */
cycle1 = ((first.data_time-1)<<4) | (first.recovery_time-2);
- cycle2 = ((second.data_time-1)<<4) | (second.recovery_time-2);
misc = ((ax - 1) << 4) | ((drdy - 2) << 1);
#ifdef OPTI621_DEBUG
- printk("%s: master: address: %d, data: %d, "
+ printk("%s: address: %d, data: %d, "
"recovery: %d, drdy: %d [clk]\n",
- hwif->name, ax, first.data_time,
+ drive->name, ax, first.data_time,
first.recovery_time, drdy);
- printk("%s: slave: address: %d, data: %d, "
- "recovery: %d, drdy: %d [clk]\n",
- hwif->name, ax, second.data_time,
- second.recovery_time, drdy);
#endif
- /* program primary drive */
- /* select Index-0 for Register-A */
- write_reg(0, MISC_REG);
+ /* select Index-0/1 for Register-A/B */
+ write_reg(drive->select.b.unit, MISC_REG);
/* set read cycle timings */
write_reg(cycle1, READ_REG);
/* set write cycle timings */
write_reg(cycle1, WRITE_REG);
- /* program secondary drive */
- /* select Index-1 for Register-B */
- write_reg(1, MISC_REG);
- /* set read cycle timings */
- write_reg(cycle2, READ_REG);
- /* set write cycle timings */
- write_reg(cycle2, WRITE_REG);
-
/* use Register-A for drive 0 */
/* use Register-B for drive 1 */
write_reg(0x85, CNTRL_REG);
spin_unlock_irqrestore(&opti621_lock, flags);
}
-static void __devinit opti621_port_init_devs(ide_hwif_t *hwif)
-{
- hwif->drives[0].drive_data = PIO_DONT_KNOW;
- hwif->drives[1].drive_data = PIO_DONT_KNOW;
-}
-
static const struct ide_port_ops opti621_port_ops = {
- .port_init_devs = opti621_port_init_devs,
.set_pio_mode = opti621_set_pio_mode,
};