1/*
2 * Copyright 2002/03, Thomas Kurschel. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6/*!	Generic PCI bus mastering IDE driver. */
7
8
9#include <ata_adapter.h>
10#include <KernelExport.h>
11
12#include <stdlib.h>
13#include <string.h>
14
15
16#define GENERIC_IDE_PCI_CONTROLLER_MODULE_NAME "busses/ata/generic_ide_pci/driver_v1"
17#define GENERIC_IDE_PCI_CHANNEL_MODULE_NAME "busses/ata/generic_ide_pci/channel/v1"
18
19#define ATA_PCI_CONTROLLER_TYPE_NAME "ata pci controller"
20
21ata_for_controller_interface *sATA;
22static ata_adapter_interface *sATAAdapter;
23device_manager_info *sDeviceManager;
24
25
26static void
27set_channel(void *cookie, ata_channel channel)
28{
29	sATAAdapter->set_channel((ata_adapter_channel_info *)cookie, channel);
30}
31
32
33static status_t
34write_command_block_regs(void *channel_cookie, ata_task_file *tf,
35	ata_reg_mask mask)
36{
37	return sATAAdapter->write_command_block_regs(
38		(ata_adapter_channel_info *)channel_cookie, tf, mask);
39}
40
41
42static status_t
43read_command_block_regs(void *channel_cookie, ata_task_file *tf,
44	ata_reg_mask mask)
45{
46	return sATAAdapter->read_command_block_regs(
47		(ata_adapter_channel_info *)channel_cookie, tf, mask);
48}
49
50
51static uint8
52get_altstatus(void *channel_cookie)
53{
54	return sATAAdapter->get_altstatus(
55		(ata_adapter_channel_info *)channel_cookie);
56}
57
58
59static status_t
60write_device_control(void *channel_cookie, uint8 val)
61{
62	return sATAAdapter->write_device_control(
63		(ata_adapter_channel_info *)channel_cookie, val);
64}
65
66
67static status_t
68write_pio(void *channel_cookie, uint16 *data, int count, bool force_16bit)
69{
70	return sATAAdapter->write_pio((ata_adapter_channel_info *)channel_cookie,
71		data, count, force_16bit);
72}
73
74
75static status_t
76read_pio(void *channel_cookie, uint16 *data, int count, bool force_16bit)
77{
78	return sATAAdapter->read_pio((ata_adapter_channel_info *)channel_cookie,
79		data, count, force_16bit);
80}
81
82
83static status_t
84prepare_dma(void *channel_cookie,
85	const physical_entry *sg_list, size_t sg_list_count,
86	bool to_device)
87{
88	return sATAAdapter->prepare_dma((ata_adapter_channel_info *)channel_cookie,
89		sg_list, sg_list_count, to_device);
90}
91
92
93static status_t
94start_dma(void *channel_cookie)
95{
96	return sATAAdapter->start_dma((ata_adapter_channel_info *)channel_cookie);
97}
98
99
100static status_t
101finish_dma(void *channel_cookie)
102{
103	return sATAAdapter->finish_dma((ata_adapter_channel_info *)channel_cookie);
104}
105
106
107static status_t
108init_channel(device_node *node, void **channel_cookie)
109{
110	return sATAAdapter->init_channel(node,
111		(ata_adapter_channel_info **)channel_cookie,
112		sizeof(ata_adapter_channel_info), sATAAdapter->inthand);
113}
114
115
116static void
117uninit_channel(void *channel_cookie)
118{
119	sATAAdapter->uninit_channel((ata_adapter_channel_info *)channel_cookie);
120}
121
122
123static void
124channel_removed(void *channel_cookie)
125{
126	sATAAdapter->channel_removed((ata_adapter_channel_info *)channel_cookie);
127}
128
129
130static status_t
131init_controller(device_node *node, ata_adapter_controller_info **cookie)
132{
133	return sATAAdapter->init_controller(node, cookie,
134		sizeof( ata_adapter_controller_info));
135}
136
137
138static void
139uninit_controller(ata_adapter_controller_info *controller)
140{
141	sATAAdapter->uninit_controller(controller);
142}
143
144
145static void
146controller_removed(ata_adapter_controller_info *controller)
147{
148	return sATAAdapter->controller_removed(controller);
149}
150
151
152static status_t
153probe_controller(device_node *parent)
154{
155	return sATAAdapter->probe_controller(parent,
156		GENERIC_IDE_PCI_CONTROLLER_MODULE_NAME, "generic_ide_pci",
157		"Generic IDE PCI Controller",
158		GENERIC_IDE_PCI_CHANNEL_MODULE_NAME,
159		true,
160		true,					// assume that command queuing works
161		1,						// assume 16 bit alignment is enough
162		0xffff,					// boundary is on 64k according to spec
163		0x10000,				// up to 64k per S/G block according to spec
164		true);					// by default, compatibility mode is used
165}
166
167
168static float
169supports_device(device_node *parent)
170{
171	const char *bus;
172	uint16 baseClass, subClass;
173
174	// make sure parent is an PCI IDE mass storage host adapter device node
175	if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false) != B_OK
176		|| sDeviceManager->get_attr_uint16(parent, B_DEVICE_TYPE, &baseClass, false) != B_OK
177		|| sDeviceManager->get_attr_uint16(parent, B_DEVICE_SUB_TYPE, &subClass, false) != B_OK)
178		return -1;
179
180	if (strcmp(bus, "pci") || baseClass != PCI_mass_storage)
181		return 0.0f;
182
183	if (subClass == PCI_ide)
184		return 0.3f;
185
186	// vendor 105a: Promise Technology, Inc.; device 4d69: 20269 (Ultra133TX2)
187	// has subClass set to PCI_mass_storage_other, and there are others as well.
188	if (subClass == PCI_mass_storage_other)
189		return 0.3f;
190
191	return 0.0f;
192}
193
194
195module_dependency module_dependencies[] = {
196	{ ATA_FOR_CONTROLLER_MODULE_NAME, (module_info **)&sATA },
197	{ B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&sDeviceManager },
198	{ ATA_ADAPTER_MODULE_NAME, (module_info **)&sATAAdapter },
199	{}
200};
201
202
203// exported interface
204static ata_controller_interface channel_interface = {
205	{
206		{
207			GENERIC_IDE_PCI_CHANNEL_MODULE_NAME,
208			0,
209			NULL
210		},
211
212		NULL,	// supports device
213		NULL,	// register device
214		init_channel,
215		uninit_channel,
216		NULL,	// register child devices
217		NULL,	// rescan
218		channel_removed,
219	},
220
221	&set_channel,
222
223	&write_command_block_regs,
224	&read_command_block_regs,
225
226	&get_altstatus,
227	&write_device_control,
228
229	&write_pio,
230	&read_pio,
231
232	&prepare_dma,
233	&start_dma,
234	&finish_dma,
235};
236
237
238static driver_module_info controller_interface = {
239	{
240		GENERIC_IDE_PCI_CONTROLLER_MODULE_NAME,
241		0,
242		NULL
243	},
244
245	supports_device,
246	probe_controller,
247	(status_t (*)(device_node *, void **))	init_controller,
248	(void (*)(void *))						uninit_controller,
249	NULL,	// register child devices
250	NULL,	// rescan
251	(void (*)(void *))						controller_removed,
252};
253
254module_info *modules[] = {
255	(module_info *)&controller_interface,
256	(module_info *)&channel_interface,
257	NULL
258};
259