• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Atari Falcon IDE Driver
3  *
4  *     Created 12 Jul 1997 by Geert Uytterhoeven
5  *
6  *  This file is subject to the terms and conditions of the GNU General Public
7  *  License.  See the file COPYING in the main directory of this archive for
8  *  more details.
9  */
10 
11 #include <linux/module.h>
12 #include <linux/types.h>
13 #include <linux/mm.h>
14 #include <linux/interrupt.h>
15 #include <linux/blkdev.h>
16 #include <linux/ide.h>
17 #include <linux/init.h>
18 
19 #include <asm/setup.h>
20 #include <asm/atarihw.h>
21 #include <asm/atariints.h>
22 #include <asm/atari_stdma.h>
23 
24 #define DRV_NAME "falconide"
25 
26     /*
27      *  Base of the IDE interface
28      */
29 
30 #define ATA_HD_BASE	0xfff00000
31 
32     /*
33      *  Offsets from the above base
34      */
35 
36 #define ATA_HD_CONTROL	0x39
37 
38     /*
39      *  falconide_intr_lock is used to obtain access to the IDE interrupt,
40      *  which is shared between several drivers.
41      */
42 
43 int falconide_intr_lock;
44 EXPORT_SYMBOL(falconide_intr_lock);
45 
falconide_input_data(ide_drive_t * drive,struct request * rq,void * buf,unsigned int len)46 static void falconide_input_data(ide_drive_t *drive, struct request *rq,
47 				 void *buf, unsigned int len)
48 {
49 	unsigned long data_addr = drive->hwif->io_ports.data_addr;
50 
51 	if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
52 		return insw(data_addr, buf, (len + 1) / 2);
53 
54 	insw_swapw(data_addr, buf, (len + 1) / 2);
55 }
56 
falconide_output_data(ide_drive_t * drive,struct request * rq,void * buf,unsigned int len)57 static void falconide_output_data(ide_drive_t *drive, struct request *rq,
58 				  void *buf, unsigned int len)
59 {
60 	unsigned long data_addr = drive->hwif->io_ports.data_addr;
61 
62 	if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
63 		return outsw(data_addr, buf, (len + 1) / 2);
64 
65 	outsw_swapw(data_addr, buf, (len + 1) / 2);
66 }
67 
68 /* Atari has a byte-swapped IDE interface */
69 static const struct ide_tp_ops falconide_tp_ops = {
70 	.exec_command		= ide_exec_command,
71 	.read_status		= ide_read_status,
72 	.read_altstatus		= ide_read_altstatus,
73 
74 	.set_irq		= ide_set_irq,
75 
76 	.tf_load		= ide_tf_load,
77 	.tf_read		= ide_tf_read,
78 
79 	.input_data		= falconide_input_data,
80 	.output_data		= falconide_output_data,
81 };
82 
83 static const struct ide_port_info falconide_port_info = {
84 	.tp_ops			= &falconide_tp_ops,
85 	.host_flags		= IDE_HFLAG_NO_DMA | IDE_HFLAG_SERIALIZE,
86 };
87 
falconide_setup_ports(hw_regs_t * hw)88 static void __init falconide_setup_ports(hw_regs_t *hw)
89 {
90 	int i;
91 
92 	memset(hw, 0, sizeof(*hw));
93 
94 	hw->io_ports.data_addr = ATA_HD_BASE;
95 
96 	for (i = 1; i < 8; i++)
97 		hw->io_ports_array[i] = ATA_HD_BASE + 1 + i * 4;
98 
99 	hw->io_ports.ctl_addr = ATA_HD_BASE + ATA_HD_CONTROL;
100 
101 	hw->irq = IRQ_MFP_IDE;
102 	hw->ack_intr = NULL;
103 
104 	hw->chipset = ide_generic;
105 }
106 
107     /*
108      *  Probe for a Falcon IDE interface
109      */
110 
falconide_init(void)111 static int __init falconide_init(void)
112 {
113 	struct ide_host *host;
114 	hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
115 	int rc;
116 
117 	if (!MACH_IS_ATARI || !ATARIHW_PRESENT(IDE))
118 		return -ENODEV;
119 
120 	printk(KERN_INFO "ide: Falcon IDE controller\n");
121 
122 	if (!request_mem_region(ATA_HD_BASE, 0x40, DRV_NAME)) {
123 		printk(KERN_ERR "%s: resources busy\n", DRV_NAME);
124 		return -EBUSY;
125 	}
126 
127 	falconide_setup_ports(&hw);
128 
129 	host = ide_host_alloc(&falconide_port_info, hws);
130 	if (host == NULL) {
131 		rc = -ENOMEM;
132 		goto err;
133 	}
134 
135 	ide_get_lock(NULL, NULL);
136 	rc = ide_host_register(host, &falconide_port_info, hws);
137 	ide_release_lock();
138 
139 	if (rc)
140 		goto err_free;
141 
142 	return 0;
143 err_free:
144 	ide_host_free(host);
145 err:
146 	release_mem_region(ATA_HD_BASE, 0x40);
147 	return rc;
148 }
149 
150 module_init(falconide_init);
151 
152 MODULE_LICENSE("GPL");
153