xref: /haiku/src/add-ons/kernel/busses/ata/it8211/it8211.c (revision b671e9bbdbd10268a042b4f4cc4317ccd03d105e)
1 /*
2  * Copyright 2008, Michael Lotz. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 #include <KernelExport.h>
6 #include <stdlib.h>
7 #include <string.h>
8 
9 #include <ata_adapter.h>
10 
11 #define IT8211_CONTROLLER_MODULE_NAME "busses/ata/it8211/driver_v1"
12 #define IT8211_CHANNEL_MODULE_NAME "busses/ata/it8211/channel/v1"
13 
14 #define PCI_VENDOR_ITE			0x1283
15 #define PCI_DEVICE_ITE_IT8211	0x8211
16 
17 static ata_adapter_interface *sATAAdapter;
18 static device_manager_info *sDeviceManager;
19 
20 
21 static void
22 it8211_set_channel(void *channelCookie, ata_channel channel)
23 {
24 	sATAAdapter->set_channel((ata_adapter_channel_info *)channelCookie,
25 		channel);
26 }
27 
28 
29 static status_t
30 it8211_write_command_block_regs(void *channelCookie, ata_task_file *taskFile,
31 	ata_reg_mask registerMask)
32 {
33 	return sATAAdapter->write_command_block_regs(
34 		(ata_adapter_channel_info *)channelCookie, taskFile, registerMask);
35 }
36 
37 
38 static status_t
39 it8211_read_command_block_regs(void *channelCookie, ata_task_file *taskFile,
40 	ata_reg_mask registerMask)
41 {
42 	return sATAAdapter->read_command_block_regs(
43 		(ata_adapter_channel_info *)channelCookie, taskFile, registerMask);
44 }
45 
46 
47 static uint8
48 it8211_get_altstatus(void *channelCookie)
49 {
50 	return sATAAdapter->get_altstatus((ata_adapter_channel_info *)channelCookie);
51 }
52 
53 
54 static status_t
55 it8211_write_device_control(void *channelCookie, uint8 value)
56 {
57 	return sATAAdapter->write_device_control(
58 		(ata_adapter_channel_info *)channelCookie, value);
59 }
60 
61 
62 static status_t
63 it8211_write_pio(void *channelCookie, uint16 *data, int count, bool force16bit)
64 {
65 	return sATAAdapter->write_pio(
66 		(ata_adapter_channel_info *)channelCookie, data, count, force16bit);
67 }
68 
69 
70 static status_t
71 it8211_read_pio(void *channelCookie, uint16 *data, int count, bool force16bit)
72 {
73 	return sATAAdapter->read_pio(
74 		(ata_adapter_channel_info *)channelCookie, data, count, force16bit);
75 }
76 
77 
78 static status_t
79 it8211_prepare_dma(void *channelCookie, const physical_entry *sgList,
80 	size_t sgListCount, bool toDevice)
81 {
82 	return sATAAdapter->prepare_dma((ata_adapter_channel_info *)channelCookie,
83 		sgList, sgListCount, toDevice);
84 }
85 
86 
87 static status_t
88 it8211_start_dma(void *channelCookie)
89 {
90 	return sATAAdapter->start_dma((ata_adapter_channel_info *)channelCookie);
91 }
92 
93 
94 static status_t
95 it8211_finish_dma(void *channelCookie)
96 {
97 	return sATAAdapter->finish_dma((ata_adapter_channel_info *)channelCookie);
98 }
99 
100 
101 static status_t
102 init_channel(device_node *node, void **channelCookie)
103 {
104 	return sATAAdapter->init_channel(node,
105 		(ata_adapter_channel_info **)channelCookie,
106 		sizeof(ata_adapter_channel_info), sATAAdapter->inthand);
107 }
108 
109 
110 static void
111 uninit_channel(void *channelCookie)
112 {
113 	sATAAdapter->uninit_channel((ata_adapter_channel_info *)channelCookie);
114 }
115 
116 
117 static void
118 channel_removed(void *channelCookie)
119 {
120 	sATAAdapter->channel_removed((ata_adapter_channel_info *)channelCookie);
121 }
122 
123 
124 static status_t
125 init_controller(device_node *node, void **cookie)
126 {
127 	return sATAAdapter->init_controller(node,
128 		(ata_adapter_controller_info **)cookie,
129 		sizeof(ata_adapter_controller_info));
130 }
131 
132 
133 static void
134 uninit_controller(void *cookie)
135 {
136 	sATAAdapter->uninit_controller((ata_adapter_controller_info *)cookie);
137 }
138 
139 
140 static void
141 controller_removed(void *cookie)
142 {
143 	sATAAdapter->controller_removed((ata_adapter_controller_info *)cookie);
144 }
145 
146 
147 static status_t
148 probe_controller(device_node *parent)
149 {
150 	return sATAAdapter->probe_controller(parent,
151 		IT8211_CONTROLLER_MODULE_NAME, "it8211",
152 		"ITE IT8211", IT8211_CHANNEL_MODULE_NAME,
153 		true,		/* DMA */
154 		true,		/* command queuing */
155 		1,			/* 16 bit alignment */
156 		0xffff,		/* 64k boundary */
157 		0x10000,	/* up to 64k per scatter/gather block */
158 		false);		/* no compatibility mode */
159 }
160 
161 
162 static float
163 supports_device(device_node *parent)
164 {
165 	const char *bus;
166 	uint16 vendorID;
167 	uint16 deviceID;
168 
169 	if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false) != B_OK
170 		|| sDeviceManager->get_attr_uint16(parent, B_DEVICE_VENDOR_ID, &vendorID, false) != B_OK
171 		|| sDeviceManager->get_attr_uint16(parent, B_DEVICE_ID, &deviceID, false) != B_OK) {
172 		return -1.0f;
173 	}
174 
175 	if (strcmp(bus, "pci") != 0 || vendorID != PCI_VENDOR_ITE
176 		|| deviceID != PCI_DEVICE_ITE_IT8211)
177 		return 0.0f;
178 
179 	return 1.0f;
180 }
181 
182 
183 module_dependency module_dependencies[] = {
184 	{ B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&sDeviceManager },
185 	{ ATA_ADAPTER_MODULE_NAME, (module_info **)&sATAAdapter },
186 	{}
187 };
188 
189 
190 // exported interface
191 static ata_controller_interface sChannelInterface = {
192 	{
193 		{
194 			IT8211_CHANNEL_MODULE_NAME,
195 			0,
196 			NULL
197 		},
198 
199 		NULL,	// supports device
200 		NULL,	// register device
201 		&init_channel,
202 		&uninit_channel,
203 		NULL,	// register child devices
204 		NULL,	// rescan
205 		&channel_removed
206 	},
207 
208 	&it8211_set_channel,
209 	&it8211_write_command_block_regs,
210 	&it8211_read_command_block_regs,
211 	&it8211_get_altstatus,
212 	&it8211_write_device_control,
213 	&it8211_write_pio,
214 	&it8211_read_pio,
215 	&it8211_prepare_dma,
216 	&it8211_start_dma,
217 	&it8211_finish_dma
218 };
219 
220 
221 static driver_module_info sControllerInterface = {
222 	{
223 		IT8211_CONTROLLER_MODULE_NAME,
224 		0,
225 		NULL
226 	},
227 
228 	&supports_device,
229 	&probe_controller,
230 	&init_controller,
231 	&uninit_controller,
232 	NULL,	// register child devices
233 	NULL,	// rescan
234 	&controller_removed
235 };
236 
237 
238 module_info *modules[] = {
239 	(module_info *)&sControllerInterface,
240 	(module_info *)&sChannelInterface,
241 	NULL
242 };
243