patch-2.3.13 linux/drivers/block/sl82c105.c
Next file: linux/drivers/block/trm290.c
Previous file: linux/drivers/block/sis5513.c
Back to the patch index
Back to the overall index
- Lines: 130
- Date:
Thu Aug 5 18:48:45 1999
- Orig file:
v2.3.12/linux/drivers/block/sl82c105.c
- Orig date:
Thu May 13 11:04:54 1999
diff -u --recursive --new-file v2.3.12/linux/drivers/block/sl82c105.c linux/drivers/block/sl82c105.c
@@ -1,3 +1,14 @@
+/*
+ * drivers/block/sl82c105.c
+ *
+ * SL82C105/Winbond 553 IDE driver
+ *
+ * Maintainer unknown.
+ *
+ * Drive tuning added from Corel Computer's kernel sources
+ * -- Russell King (15/11/98) linux@arm.linux.org.uk
+ */
+
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
@@ -15,9 +26,108 @@
#include "ide_modes.h"
+#ifdef CONFIG_ARCH_NETWINDER
+/*
+ * Convert a PIO mode and cycle time to the required on/off
+ * times for the interface. This has protection against run-away
+ * timings.
+ */
+static unsigned int get_timing_sl82c105(ide_pio_data_t *p)
+{
+ unsigned int cmd_on;
+ unsigned int cmd_off;
+
+ cmd_on = (ide_pio_timings[p->pio_mode].active_time + 29) / 30;
+ cmd_off = (p->cycle_time - 30 * cmd_on + 29) / 30;
+
+ if (cmd_on > 32)
+ cmd_on = 32;
+ if (cmd_on == 0)
+ cmd_on = 1;
+
+ if (cmd_off > 32)
+ cmd_off = 32;
+ if (cmd_off == 0)
+ cmd_off = 1;
+
+ return (cmd_on - 1) << 8 | (cmd_off - 1);
+}
+
+/*
+ * Tell the drive to enable the specified PIO mode.
+ * This should be in ide.c, maybe as a special command
+ * (see do_special).
+ */
+static int ide_set_drive_pio_mode(ide_drive_t *drive, byte pio)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+
+ if (pio > 2) {
+ /* FIXME: I don't believe that this SELECT_DRIVE is required,
+ * since ide.c only calls tuneproc from do_special, after
+ * the correct drive has been selected.
+ */
+ SELECT_DRIVE(hwif, drive);
+ OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG);
+ OUT_BYTE(0x08 | pio, IDE_NSECTOR_REG);
+ OUT_BYTE(0x03, IDE_FEATURE_REG);
+ OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
+
+ if (ide_wait_stat(drive, DRIVE_READY,
+ BUSY_STAT|DRQ_STAT|ERR_STAT, WAIT_CMD)) {
+ printk("%s: drive not ready for command\n",
+ drive->name);
+ return 1;
+ }
+
+ OUT_BYTE(drive->ctl, IDE_CONTROL_REG);
+ }
+
+ return 0;
+}
+
+/*
+ * We only deal with PIO mode here - DMA mode 'using_dma' is not
+ * initialised at the point that this function is called.
+ */
+static void tune_sl82c105(ide_drive_t *drive, byte pio)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ struct pci_dev *dev = hwif->pci_dev;
+ ide_pio_data_t p;
+ unsigned int drv_ctrl = 0x909;
+
+ pio = ide_get_best_pio_mode(drive, pio, 5, &p);
+
+ if (!ide_set_drive_pio_mode(drive, pio)) {
+ drv_ctrl = get_timing_sl82c105(&p);
+
+ if (p.use_iordy)
+ drv_ctrl |= 0x40;
+ }
+
+ pci_write_config_word(dev,
+ (hwif->channel ? 0x4c : 0x44)
+ + (drive->select.b.unit ? 4 : 0),
+ drv_ctrl);
+
+ printk("%s: selected PIO mode %d (%dns)\n",
+ drive->name, p.pio_mode, p.cycle_time);
+}
+#endif
+
void ide_init_sl82c105(ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
+
+#ifdef CONFIG_ARCH_NETWINDER
+ unsigned char ctrl_stat;
+
+ pci_read_config_byte(dev, 0x40, &ctrl_stat);
+ pci_write_config_byte(dev, 0x40, ctrl_stat | 0x33);
+
+ hwif->tuneproc = tune_sl82c105;
+#else
unsigned short t16;
unsigned int t32;
pci_read_config_word(dev, PCI_COMMAND, &t16);
@@ -33,4 +143,5 @@
printk("IDE control/status register: %08x\n",t32);
pci_write_config_dword(dev, 0x40, 0x10ff08a1);
#endif /* CONFIG_MBX */
+#endif
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)