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
17static ata_adapter_interface *sATAAdapter;
18static device_manager_info *sDeviceManager;
19
20
21static void
22it8211_set_channel(void *channelCookie, ata_channel channel)
23{
24	sATAAdapter->set_channel((ata_adapter_channel_info *)channelCookie,
25		channel);
26}
27
28
29static status_t
30it8211_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
38static status_t
39it8211_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
47static uint8
48it8211_get_altstatus(void *channelCookie)
49{
50	return sATAAdapter->get_altstatus((ata_adapter_channel_info *)channelCookie);
51}
52
53
54static status_t
55it8211_write_device_control(void *channelCookie, uint8 value)
56{
57	return sATAAdapter->write_device_control(
58		(ata_adapter_channel_info *)channelCookie, value);
59}
60
61
62static status_t
63it8211_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
70static status_t
71it8211_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
78static status_t
79it8211_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
87static status_t
88it8211_start_dma(void *channelCookie)
89{
90	return sATAAdapter->start_dma((ata_adapter_channel_info *)channelCookie);
91}
92
93
94static status_t
95it8211_finish_dma(void *channelCookie)
96{
97	return sATAAdapter->finish_dma((ata_adapter_channel_info *)channelCookie);
98}
99
100
101static status_t
102init_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
110static void
111uninit_channel(void *channelCookie)
112{
113	sATAAdapter->uninit_channel((ata_adapter_channel_info *)channelCookie);
114}
115
116
117static void
118channel_removed(void *channelCookie)
119{
120	sATAAdapter->channel_removed((ata_adapter_channel_info *)channelCookie);
121}
122
123
124static status_t
125init_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
133static void
134uninit_controller(void *cookie)
135{
136	sATAAdapter->uninit_controller((ata_adapter_controller_info *)cookie);
137}
138
139
140static void
141controller_removed(void *cookie)
142{
143	sATAAdapter->controller_removed((ata_adapter_controller_info *)cookie);
144}
145
146
147static status_t
148probe_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
162static float
163supports_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
183module_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
191static 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
221static 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
238module_info *modules[] = {
239	(module_info *)&sControllerInterface,
240	(module_info *)&sChannelInterface,
241	NULL
242};
243