ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / ide / legacy / pc9800.c
1 /*
2  *  ide_pc9800.c
3  *
4  *  Copyright (C) 1997-2000  Linux/98 project,
5  *                           Kyoto University Microcomputer Club.
6  */
7
8 #include <linux/config.h>
9 #include <linux/kernel.h>
10 #include <linux/ioport.h>
11 #include <linux/ide.h>
12 #include <linux/init.h>
13
14 #include <asm/io.h>
15 #include <asm/pc9800.h>
16
17 #define PC9800_IDE_BANKSELECT   0x432
18
19 #undef PC9800_IDE_DEBUG
20
21 static void pc9800_select(ide_drive_t *drive)
22 {
23 #ifdef PC9800_IDE_DEBUG
24         byte old;
25
26         /* Too noisy: */
27         /* printk(KERN_DEBUG "pc9800_select(%s)\n", drive->name); */
28
29         outb(0x80, PC9800_IDE_BANKSELECT);
30         old = inb(PC9800_IDE_BANKSELECT);
31         if (old != HWIF(drive)->index)
32                 printk(KERN_DEBUG "ide-pc9800: switching bank #%d -> #%d\n",
33                         old, HWIF(drive)->index);
34 #endif
35         outb(HWIF(drive)->index, PC9800_IDE_BANKSELECT);
36 }
37
38 void __init ide_probe_for_pc9800(void)
39 {
40         u8 saved_bank;
41
42         if (!PC9800_9821_P() /* || !PC9821_IDEIF_DOUBLE_P() */)
43                 return;
44
45         if (!request_region(PC9800_IDE_BANKSELECT, 1, "ide0/1 bank")) {
46                 printk(KERN_ERR
47                         "ide: bank select port (%#x) is already occupied!\n",
48                         PC9800_IDE_BANKSELECT);
49                 return;
50         }
51
52         /* Do actual probing. */
53         if ((saved_bank = inb(PC9800_IDE_BANKSELECT)) == (u8) ~0
54             || (outb(saved_bank ^ 1, PC9800_IDE_BANKSELECT),
55                 /* Next outb is dummy for reading status. */
56                 outb(0x80, PC9800_IDE_BANKSELECT),
57                 inb(PC9800_IDE_BANKSELECT) != (saved_bank ^ 1))) {
58                 printk(KERN_INFO
59                         "ide: pc9800 type bank selecting port not found\n");
60                 release_region(PC9800_IDE_BANKSELECT, 1);
61                 return;
62         }
63
64         /* Restore original value, just in case. */
65         outb(saved_bank, PC9800_IDE_BANKSELECT);
66
67         /* These ports are reseved by IDE I/F.  */
68         if (!request_region(0x430, 1, "ide") ||
69             !request_region(0x435, 1, "ide")) {
70                 printk(KERN_WARNING
71                         "ide: IO port 0x430 and 0x435 are reserved for IDE"
72                         " the card using these ports may not work\n");
73         }
74
75         if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET] == HD_DATA &&
76             ide_hwifs[1].io_ports[IDE_DATA_OFFSET] == HD_DATA) {
77                 ide_hwifs[0].chipset = ide_pc9800;
78                 ide_hwifs[0].mate = &ide_hwifs[1];
79                 ide_hwifs[0].selectproc = pc9800_select;
80                 ide_hwifs[1].chipset = ide_pc9800;
81                 ide_hwifs[1].mate = &ide_hwifs[0];
82                 ide_hwifs[1].selectproc = pc9800_select;
83         }
84 }