1/*
2 * Copyright 2006-2009, Marcus Overhagen. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6#include <KernelExport.h>
7#include <stdlib.h>
8#include <string.h>
9
10#include <ata_adapter.h>
11#include <tracing.h>
12
13#define TRACE(x...)	do { dprintf("si-3112: " x); ktrace_printf("si-3112: " x); } while (0)
14//#define FLOW(x...)	ktrace_printf("si-3112: " x)
15#define FLOW(x...)
16
17
18#define DRIVER_PRETTY_NAME		"Silicon Image SATA"
19#define CONTROLLER_NAME			DRIVER_PRETTY_NAME
20#define CONTROLLER_MODULE_NAME	"busses/ata/silicon_image_3112/driver_v1"
21#define CHANNEL_MODULE_NAME		"busses/ata/silicon_image_3112/channel/v1"
22
23enum asic_type {
24	ASIC_SI3112 = 0,
25	ASIC_SI3114 = 1,
26};
27
28static const struct {
29	uint16 channel_count;
30	uint32 mmio_bar_size;
31	const char *asic_name;
32} kASICData[2] = {
33	{ 2, 0x200, "si3112" },
34	{ 4, 0x400, "si3114" },
35};
36
37static const struct {
38	uint16 cmd;
39	uint16 ctl;
40	uint16 bmdma;
41	uint16 sien;
42	uint16 stat;
43	const char *name;
44} kControllerChannelData[] = {
45	{  0x80,  0x8A,  0x00, 0x148,  0xA0, "Primary Channel" },
46	{  0xC0,  0xCA,  0x08, 0x1C8,  0xE0, "Secondary Channel" },
47	{ 0x280, 0x28A, 0x200, 0x348, 0x2A0, "Tertiary Channel" },
48	{ 0x2C0, 0x2CA, 0x208, 0x3C8, 0x2E0, "Quaternary Channel" },
49};
50
51#define SI_SYSCFG 			0x48
52#define SI_BMDMA2			0x200
53#define SI_INT_STEERING 	0x02
54#define SI_MASK_2PORT		((1 << 22) | (1 << 23))
55#define SI_MASK_4PORT		((1 << 22) | (1 << 23) | (1 << 24) | (1 << 25))
56
57struct channel_data;
58
59typedef struct controller_data {
60	pci_device_module_info *pci;
61	pci_device *device;
62
63	device_node *node;
64
65	struct channel_data *channel[4]; // XXX only for interrupt workaround
66	int channel_count; // XXX only for interrupt workaround
67
68	uint32 asic_index;
69	uint32 int_num;
70
71	area_id mmio_area;
72	addr_t mmio_addr;
73
74	uint32 lost;			// != 0 if device got removed, i.e. if it must not
75							// be accessed anymore
76} controller_data;
77
78
79typedef struct channel_data {
80	pci_device_module_info *pci;
81	device_node *		node;
82	pci_device *		device;
83	ata_channel			ataChannel;
84
85	volatile uint8 *	task_file;
86	volatile uint8 *	control_block;
87	volatile uint8 *	command_block;
88	volatile uint8 *	dev_ctrl;
89	volatile uint8 *	bm_status_reg;
90	volatile uint8 *	bm_command_reg;
91	volatile uint32 *	bm_prdt_address;
92
93	volatile uint32 *	stat;
94
95	area_id				prd_area;
96	prd_entry *			prdt;
97	phys_addr_t			prdt_phys;
98	uint32 				dma_active;
99	uint32 				lost;
100} channel_data;
101
102
103static ata_for_controller_interface* sATA;
104static ata_adapter_interface* sATAAdapter;
105static device_manager_info* sDeviceManager;
106
107static status_t device_control_write(void *channel_cookie, uint8 val);
108static int32 handle_interrupt(void *arg);
109
110
111static float
112controller_supports(device_node *parent)
113{
114	const char *bus;
115	uint16 vendorID;
116	uint16 deviceID;
117
118	// get the bus (should be PCI)
119	if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false) != B_OK
120		|| strcmp(bus, "pci") != 0)
121		return B_ERROR;
122
123	// get vendor and device ID
124	if (sDeviceManager->get_attr_uint16(parent, B_DEVICE_VENDOR_ID, &vendorID, false) != B_OK
125		|| sDeviceManager->get_attr_uint16(parent, B_DEVICE_ID, &deviceID, false) != B_OK) {
126		return B_ERROR;
127	}
128
129	#define ID(v, d) (((v) << 16) | (d))
130	switch (ID(vendorID, deviceID)) {
131		case ID(0x1095, 0x0240):
132		case ID(0x1095, 0x3112):
133		case ID(0x1095, 0x3114):
134		case ID(0x1095, 0x3512):
135		case ID(0x1002, 0x436e): // ATI
136		case ID(0x1002, 0x4379): // ATI
137		case ID(0x1002, 0x437a): // ATI
138			break;
139		default:
140			return 0.0f;
141	}
142
143	TRACE("controller found! vendor 0x%04x, device 0x%04x\n", vendorID, deviceID);
144
145	return 0.8f;
146}
147
148
149static status_t
150controller_probe(device_node *parent)
151{
152	pci_device *device;
153	pci_device_module_info *pci;
154	uint32 mmioBase;
155	uint16 deviceID;
156	uint16 vendorID;
157	uint8 interruptNumber;
158	int asicIndex;
159
160	TRACE("controller_probe\n");
161
162	sDeviceManager->get_driver(parent, (driver_module_info **)&pci, (void **)&device);
163
164	deviceID = pci->read_pci_config(device, PCI_device_id, 2);
165	vendorID = pci->read_pci_config(device, PCI_vendor_id, 2);
166	interruptNumber = pci->read_pci_config(device, PCI_interrupt_line, 1);
167	mmioBase = pci->read_pci_config(device, PCI_base_registers + 20, 4)
168		& PCI_address_io_mask;
169
170	switch (ID(vendorID, deviceID)) {
171		case ID(0x1095, 0x0240):
172		case ID(0x1095, 0x3112):
173		case ID(0x1095, 0x3512):
174		case ID(0x1002, 0x436e): // ATI
175		case ID(0x1002, 0x4379): // ATI
176		case ID(0x1002, 0x437a): // ATI
177			asicIndex = ASIC_SI3112;
178			break;
179		case ID(0x1095, 0x3114):
180			asicIndex = ASIC_SI3114;
181			break;
182		default:
183			TRACE("unsupported asic\n");
184			return B_ERROR;
185	}
186
187	if (!mmioBase) {
188		TRACE("mmio not configured\n");
189		return B_ERROR;
190	}
191
192	if (interruptNumber == 0 || interruptNumber == 0xff) {
193		TRACE("irq not configured\n");
194		return B_ERROR;
195	}
196
197	{
198		io_resource resources[2] = {
199			{ B_IO_MEMORY, mmioBase, kASICData[asicIndex].mmio_bar_size },
200			{}
201		};
202		device_attr attrs[] = {
203			// properties of this controller for ATA bus manager
204			// there are always max. 2 devices
205			// (unless this is a Compact Flash Card with a built-in ATA
206			// controller, which has exactly 1 device)
207			{ ATA_CONTROLLER_MAX_DEVICES_ITEM, B_UINT8_TYPE,
208				{ .ui8 = kASICData[asicIndex].channel_count }},
209			// of course we can DMA
210			{ ATA_CONTROLLER_CAN_DMA_ITEM, B_UINT8_TYPE, { .ui8 = true }},
211			// choose any name here
212			{ ATA_CONTROLLER_CONTROLLER_NAME_ITEM, B_STRING_TYPE,
213				{ .string = CONTROLLER_NAME }},
214
215			// DMA properties
216			// data must be word-aligned;
217			// warning: some controllers are more picky!
218			{ B_DMA_ALIGNMENT, B_UINT32_TYPE, { .ui32 = 1}},
219			// one S/G block must not cross 64K boundary
220			{ B_DMA_BOUNDARY, B_UINT32_TYPE, { .ui32 = 0xffff }},
221			// max size of S/G block is 16 bits with zero being 64K
222			{ B_DMA_MAX_SEGMENT_BLOCKS, B_UINT32_TYPE, { .ui32 = 0x10000 }},
223			{ B_DMA_MAX_SEGMENT_COUNT, B_UINT32_TYPE,
224				{ .ui32 = ATA_ADAPTER_MAX_SG_COUNT }},
225			{ B_DMA_HIGH_ADDRESS, B_UINT64_TYPE, { .ui64 = 0x100000000LL }},
226
227			// private data to find controller
228			{ "silicon_image_3112/asic_index", B_UINT32_TYPE,
229				{ .ui32 = asicIndex }},
230			{ "silicon_image_3112/mmio_base", B_UINT32_TYPE,
231				{ .ui32 = mmioBase }},
232			{ "silicon_image_3112/int_num", B_UINT32_TYPE,
233				{ .ui32 = interruptNumber }},
234			{ NULL }
235		};
236
237		TRACE("publishing controller\n");
238
239		return sDeviceManager->register_node(parent, CONTROLLER_MODULE_NAME, attrs,
240			resources, NULL);
241	}
242}
243
244
245static status_t
246controller_init(device_node *node, void **_controllerCookie)
247{
248	controller_data *controller;
249	device_node *parent;
250	pci_device_module_info *pci;
251	pci_device *device;
252	uint32 asicIndex;
253	uint32 mmioBase;
254	addr_t mmioAddr;
255	area_id mmioArea;
256	uint32 interruptNumber;
257	status_t res;
258	uint32 temp;
259	int i;
260
261	TRACE("controller_init\n");
262
263	if (sDeviceManager->get_attr_uint32(node, "silicon_image_3112/asic_index", &asicIndex, false) != B_OK)
264		return B_ERROR;
265	if (sDeviceManager->get_attr_uint32(node, "silicon_image_3112/mmio_base", &mmioBase, false) != B_OK)
266		return B_ERROR;
267	if (sDeviceManager->get_attr_uint32(node, "silicon_image_3112/int_num", &interruptNumber, false) != B_OK)
268		return B_ERROR;
269
270	controller = malloc(sizeof(controller_data));
271	if (!controller)
272		return B_NO_MEMORY;
273
274	FLOW("controller %p\n", controller);
275
276	mmioArea = map_physical_memory("Silicon Image SATA regs", mmioBase,
277		kASICData[asicIndex].mmio_bar_size, B_ANY_KERNEL_ADDRESS,
278		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void **)&mmioAddr);
279	if (mmioArea < B_OK) {
280		TRACE("controller_init: mapping memory failed\n");
281		free(controller);
282		return B_ERROR;
283	}
284
285	parent = sDeviceManager->get_parent_node(node);
286	sDeviceManager->get_driver(parent, (driver_module_info **)&pci, (void **)&device);
287	sDeviceManager->put_node(parent);
288
289	TRACE("asic index %" B_PRId32 "\n", asicIndex);
290	TRACE("asic name %s\n", kASICData[asicIndex].asic_name);
291	TRACE("int num %" B_PRId32 "\n", interruptNumber);
292	TRACE("mmio addr %" B_PRIxADDR"\n", mmioAddr);
293
294	controller->pci = pci;
295	controller->device = device;
296	controller->node = node;
297	controller->asic_index = asicIndex;
298	controller->int_num = interruptNumber;
299	controller->mmio_area = mmioArea;
300	controller->mmio_addr = mmioAddr;
301	controller->lost = 0;
302
303	controller->channel_count = kASICData[asicIndex].channel_count;
304	for (i = 0; i < kASICData[asicIndex].channel_count; i++)
305		controller->channel[i] = 0;
306
307	if (asicIndex == ASIC_SI3114) {
308		// I put a magic spell on you
309		temp = *(volatile uint32 *)(mmioAddr + SI_BMDMA2);
310		*(volatile uint32 *)(mmioAddr + SI_BMDMA2) = temp | SI_INT_STEERING;
311		*(volatile uint32 *)(mmioAddr + SI_BMDMA2); // flush
312	}
313
314	// disable all sata phy interrupts
315	for (i = 0; i < kASICData[asicIndex].channel_count; i++)
316		*(volatile uint32 *)(mmioAddr + kControllerChannelData[i].sien) = 0;
317	*(volatile uint32 *)(mmioAddr + kControllerChannelData[0].sien); // flush
318
319	// install interrupt handler
320	res = install_io_interrupt_handler(interruptNumber, handle_interrupt,
321		controller, 0);
322	if (res < B_OK) {
323		TRACE("controller_init: installing interrupt handler failed\n");
324		delete_area(mmioArea);
325		free(controller);
326		return res;
327	}
328
329	// unmask interrupts
330	temp = *(volatile uint32 *)(mmioAddr + SI_SYSCFG);
331	temp &= (asicIndex == ASIC_SI3114) ? (~SI_MASK_4PORT) : (~SI_MASK_2PORT);
332	*(volatile uint32 *)(mmioAddr + SI_SYSCFG) = temp;
333	*(volatile uint32 *)(mmioAddr + SI_SYSCFG); // flush
334
335	*_controllerCookie = controller;
336
337	TRACE("controller_init success\n");
338	return B_OK;
339}
340
341
342static void
343controller_uninit(void *controllerCookie)
344{
345	controller_data *controller = controllerCookie;
346	uint32 temp;
347
348	TRACE("controller_uninit enter\n");
349
350	// disable interrupts
351	temp = *(volatile uint32 *)(controller->mmio_addr + SI_SYSCFG);
352	temp |= (controller->asic_index == ASIC_SI3114) ? SI_MASK_4PORT : SI_MASK_2PORT;
353	*(volatile uint32 *)(controller->mmio_addr + SI_SYSCFG) = temp;
354	*(volatile uint32 *)(controller->mmio_addr + SI_SYSCFG); // flush
355
356	remove_io_interrupt_handler(controller->int_num, handle_interrupt,
357		controller);
358
359	delete_area(controller->mmio_area);
360	free(controller);
361
362	TRACE("controller_uninit leave\n");
363}
364
365
366static status_t
367controller_register_channels(void *cookie)
368{
369	controller_data *controller = cookie;
370	int index;
371
372	// publish channel nodes
373	for (index = 0; index < kASICData[controller->asic_index].channel_count;
374			index++) {
375		device_attr attrs[] = {
376			{ B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { .string = DRIVER_PRETTY_NAME }},
377//			{ PNP_DRIVER_CONNECTION, B_STRING_TYPE, { .string = kControllerChannelData[channelIndex].name }},
378			{ B_DEVICE_FIXED_CHILD, B_STRING_TYPE, { .string = ATA_FOR_CONTROLLER_MODULE_NAME }},
379
380			// private data to identify channel
381			{ ATA_CONTROLLER_CAN_DMA_ITEM, B_UINT8_TYPE, { .ui8 = true }},
382			{ "silicon_image_3112/chan_index", B_UINT32_TYPE, { .ui32 = index }},
383			{ NULL }
384		};
385
386		TRACE("publishing %s\n", kControllerChannelData[index].name);
387
388		sDeviceManager->register_node(controller->node, CHANNEL_MODULE_NAME, attrs,
389			NULL, NULL);
390	}
391
392	return B_OK;
393}
394
395
396static void
397controller_removed(void *controllerCookie)
398{
399	controller_data *controller = controllerCookie;
400	controller->lost = 1;
401}
402
403
404//	#pragma mark -
405
406
407static status_t
408channel_init(device_node *node, void **_channelCookie)
409{
410	controller_data *controller;
411	device_node *parent;
412	channel_data *channel;
413	physical_entry entry;
414	size_t prdtSize;
415	uint32 channelIndex;
416
417	TRACE("channel_init enter\n");
418
419	channel = malloc(sizeof(channel_data));
420	if (!channel)
421		return B_NO_MEMORY;
422
423	if (sDeviceManager->get_attr_uint32(node, "silicon_image_3112/chan_index", &channelIndex, false) != B_OK)
424		goto err;
425
426#if 0
427	if (1 /* debug */){
428		uint8 bus, device, function;
429		uint16 vendorID, deviceID;
430		sDeviceManager->get_attr_uint8(node, PCI_DEVICE_BUS_ITEM, &bus, true);
431		sDeviceManager->get_attr_uint8(node, PCI_DEVICE_DEVICE_ITEM, &device, true);
432		sDeviceManager->get_attr_uint8(node, PCI_DEVICE_FUNCTION_ITEM, &function, true);
433		sDeviceManager->get_attr_uint16(node, PCI_DEVICE_VENDOR_ID_ITEM, &vendorID, true);
434		sDeviceManager->get_attr_uint16(node, PCI_DEVICE_DEVICE_ID_ITEM, &deviceID, true);
435		TRACE("bus %3d, device %2d, function %2d: vendor %04x, device %04x\n",
436			bus, device, function, vendorID, deviceID);
437	}
438#endif
439
440	TRACE("channel_index %" B_PRId32 "\n", channelIndex);
441	TRACE("channel name: %s\n", kControllerChannelData[channelIndex].name);
442
443	TRACE("channel %p\n", channel);
444
445	parent = sDeviceManager->get_parent_node(node);
446	sDeviceManager->get_driver(parent, NULL, (void **)&controller);
447	sDeviceManager->put_node(parent);
448
449	TRACE("controller %p\n", controller);
450	TRACE("mmio_addr %p\n", (void *)controller->mmio_addr);
451
452	// PRDT must be contiguous, dword-aligned and must not cross 64K boundary
453// TODO: Where's the handling for the 64 K boundary? create_area_etc() can be
454// used.
455	prdtSize = (ATA_ADAPTER_MAX_SG_COUNT * sizeof(prd_entry) + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1);
456	channel->prd_area = create_area("prd", (void **)&channel->prdt,
457		B_ANY_KERNEL_ADDRESS, prdtSize, B_32_BIT_CONTIGUOUS,
458		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
459	if (channel->prd_area < B_OK) {
460		TRACE("creating prd_area failed\n");
461		goto err;
462	}
463
464	get_memory_map(channel->prdt, prdtSize, &entry, 1);
465	channel->prdt_phys = entry.address;
466
467	channel->pci = controller->pci;
468	channel->device = controller->device;
469	channel->node = node;
470	channel->ataChannel = NULL;
471
472	channel->task_file = (volatile uint8 *)(controller->mmio_addr + kControllerChannelData[channelIndex].cmd + 1);
473	channel->control_block = (volatile uint8 *)(controller->mmio_addr + kControllerChannelData[channelIndex].ctl);
474	channel->command_block = (volatile uint8 *)(controller->mmio_addr + kControllerChannelData[channelIndex].cmd);
475	channel->dev_ctrl = (volatile uint8 *)(controller->mmio_addr + kControllerChannelData[channelIndex].ctl);
476	channel->bm_prdt_address = (volatile uint32 *)(controller->mmio_addr + kControllerChannelData[channelIndex].bmdma + ATA_BM_PRDT_ADDRESS);
477	channel->bm_status_reg = (volatile uint8 *)(controller->mmio_addr + kControllerChannelData[channelIndex].bmdma + ATA_BM_STATUS_REG);
478	channel->bm_command_reg = (volatile uint8 *)(controller->mmio_addr + kControllerChannelData[channelIndex].bmdma + ATA_BM_COMMAND_REG);
479	channel->stat = (volatile uint32 *)(controller->mmio_addr + kControllerChannelData[channelIndex].stat);
480
481	channel->lost = 0;
482	channel->dma_active = 0;
483
484	controller->channel[channelIndex] = channel;
485
486	// disable interrupts
487	device_control_write(channel, ATA_DEVICE_CONTROL_BIT3
488		| ATA_DEVICE_CONTROL_DISABLE_INTS);
489
490	*_channelCookie = channel;
491
492	TRACE("channel_init leave\n");
493	return B_OK;
494
495err:
496	free(channel);
497	return B_ERROR;
498}
499
500
501static void
502channel_uninit(void *channelCookie)
503{
504	channel_data *channel = channelCookie;
505
506	TRACE("channel_uninit enter\n");
507
508	// disable interrupts
509	device_control_write(channel, ATA_DEVICE_CONTROL_BIT3
510		| ATA_DEVICE_CONTROL_DISABLE_INTS);
511
512	delete_area(channel->prd_area);
513	free(channel);
514
515	TRACE("channel_uninit leave\n");
516}
517
518
519static void
520channel_removed(void *channelCookie)
521{
522	channel_data *channel = channelCookie;
523	channel->lost = 1;
524}
525
526
527static void
528set_channel(void *channelCookie, ata_channel ataChannel)
529{
530	channel_data *channel = channelCookie;
531	channel->ataChannel = ataChannel;
532}
533
534
535static status_t
536task_file_write(void *channelCookie, ata_task_file *tf, ata_reg_mask mask)
537{
538	channel_data *channel = channelCookie;
539	int i;
540
541	FLOW("task_file_write\n");
542
543	if (channel->lost)
544		return B_ERROR;
545
546	for (i = 0; i < 7; i++) {
547		if( ((1 << (i+7)) & mask) != 0 ) {
548			FLOW("%x->HI(%x)\n", tf->raw.r[i + 7], i );
549			channel->task_file[i] = tf->raw.r[i + 7];
550		}
551
552		if (((1 << i) & mask) != 0) {
553			FLOW("%x->LO(%x)\n", tf->raw.r[i], i );
554			channel->task_file[i] = tf->raw.r[i];
555		}
556	}
557	*channel->dev_ctrl; // read altstatus to flush
558
559	return B_OK;
560}
561
562
563static status_t
564task_file_read(void *channelCookie, ata_task_file *tf, ata_reg_mask mask)
565{
566	channel_data *channel = channelCookie;
567	int i;
568
569	FLOW("task_file_read\n");
570
571	if (channel->lost)
572		return B_ERROR;
573
574	for (i = 0; i < 7; i++) {
575		if (((1 << i) & mask) != 0) {
576			tf->raw.r[i] = channel->task_file[i];
577			FLOW("%x: %x\n", i, (int)tf->raw.r[i] );
578		}
579	}
580
581	return B_OK;
582}
583
584
585static uint8
586altstatus_read(void *channelCookie)
587{
588	channel_data *channel = channelCookie;
589
590	FLOW("altstatus_read\n");
591
592	if (channel->lost)
593		return 0x01; // Error bit
594
595	return *channel->dev_ctrl;
596}
597
598
599static status_t
600device_control_write(void *channelCookie, uint8 val)
601{
602	channel_data *channel = channelCookie;
603
604	FLOW("device_control_write 0x%x\n", val);
605
606	if (channel->lost)
607		return B_ERROR;
608
609	*channel->dev_ctrl = val;
610	*channel->dev_ctrl; // read altstatus to flush
611
612	return B_OK;
613}
614
615
616static status_t
617pio_write(void *channelCookie, uint16 *data, int count, bool force_16bit)
618{
619	channel_data *channel = channelCookie;
620	if (channel->lost)
621		return B_ERROR;
622
623	FLOW("pio_write force_16bit = %d, (count & 1) = %d\n", force_16bit, (count & 1));
624
625	// The data port is only 8 bit wide in the command register block.
626
627	if ((count & 1) != 0 || force_16bit) {
628		volatile uint16 * base = (volatile uint16 *)channel->command_block;
629		for ( ; count > 0; --count)
630			*base = *(data++);
631	} else {
632		volatile uint32 * base = (volatile uint32 *)channel->command_block;
633		uint32 *cur_data = (uint32 *)data;
634
635		for ( ; count > 0; count -= 2 )
636			*base = *(cur_data++);
637	}
638	*channel->dev_ctrl; // read altstatus to flush
639
640	return B_OK;
641}
642
643
644static status_t
645pio_read(void *channelCookie, uint16 *data, int count, bool force_16bit)
646{
647	channel_data *channel = channelCookie;
648	if (channel->lost)
649		return B_ERROR;
650
651	FLOW("pio_read force_16bit = %d, (count & 1) = %d\n", force_16bit, (count & 1));
652
653	// The data port is only 8 bit wide in the command register block.
654	// We are memory mapped and read using 16 or 32 bit access from this 8 bit location.
655
656	if ((count & 1) != 0 || force_16bit) {
657		volatile uint16 * base = (volatile uint16 *)channel->command_block;
658		for ( ; count > 0; --count)
659			*(data++) = *base;
660	} else {
661		volatile uint32 * base = (volatile uint32 *)channel->command_block;
662		uint32 *cur_data = (uint32 *)data;
663
664		for ( ; count > 0; count -= 2 )
665			*(cur_data++) = *base;
666	}
667
668	return B_OK;
669}
670
671
672static status_t
673dma_prepare(void *channelCookie, const physical_entry *sg_list,
674	size_t sg_list_count, bool write)
675{
676	channel_data *channel = channelCookie;
677	pci_device_module_info *pci = channel->pci;
678	pci_device *device = channel->device;
679	prd_entry *prd = channel->prdt;
680	uint8 command;
681	uint8 status;
682	uint32 temp;
683	int i;
684
685	FLOW("dma_prepare enter\n");
686
687	for (i = sg_list_count - 1, prd = channel->prdt; i >= 0;
688			--i, ++prd, ++sg_list ) {
689		prd->address = B_HOST_TO_LENDIAN_INT32((uint32)pci->ram_address(device,
690			sg_list->address));
691
692		// 0 means 64K - this is done automatically by discarding upper 16 bits
693		prd->count = B_HOST_TO_LENDIAN_INT16((uint16)sg_list->size);
694		prd->EOT = i == 0;
695
696		FLOW("%" B_PRIx32", %" B_PRId16", %" B_PRId8"\n", prd->address, prd->count, prd->EOT);
697	}
698
699	// XXX move this to chan init?
700	temp = (*channel->bm_prdt_address) & 3;
701	temp |= B_HOST_TO_LENDIAN_INT32((uint32)pci->ram_address(device,
702		channel->prdt_phys)) & ~3;
703	*channel->bm_prdt_address = temp;
704
705	*channel->dev_ctrl; // read altstatus to flush
706
707	// reset interrupt and error signal
708	status = *channel->bm_status_reg | ATA_BM_STATUS_INTERRUPT
709		| ATA_BM_STATUS_ERROR;
710	*channel->bm_status_reg = status;
711
712	*channel->dev_ctrl; // read altstatus to flush
713
714	// set data direction
715	command = *channel->bm_command_reg;
716	if (write)
717		command &= ~ATA_BM_COMMAND_READ_FROM_DEVICE;
718	else
719		command |= ATA_BM_COMMAND_READ_FROM_DEVICE;
720
721	*channel->bm_command_reg = command;
722
723	*channel->dev_ctrl; // read altstatus to flush
724
725	FLOW("dma_prepare leave\n");
726
727	return B_OK;
728}
729
730
731static status_t
732dma_start(void *channelCookie)
733{
734	channel_data *channel = channelCookie;
735	uint8 command;
736
737	FLOW("dma_start enter\n");
738
739	command = *channel->bm_command_reg | ATA_BM_COMMAND_START_STOP;
740	channel->dma_active = true;
741	*channel->bm_command_reg = command;
742
743	*channel->dev_ctrl; // read altstatus to flush
744
745	FLOW("dma_start leave\n");
746
747	return B_OK;
748}
749
750
751static status_t
752dma_finish(void *channelCookie)
753{
754	channel_data *channel = channelCookie;
755	uint8 command;
756	uint8 status;
757
758	FLOW("dma_finish enter\n");
759
760	status = *channel->bm_status_reg;
761
762	command = *channel->bm_command_reg;
763	*channel->bm_command_reg = command & ~ATA_BM_COMMAND_START_STOP;
764
765	channel->dma_active = false;
766
767	*channel->bm_status_reg = status | ATA_BM_STATUS_ERROR;
768	*channel->dev_ctrl; // read altstatus to flush
769
770	if ((status & ATA_BM_STATUS_ACTIVE) != 0) {
771		TRACE("dma_finish: buffer too large\n");
772		return B_DEV_DATA_OVERRUN;
773	}
774	if ((status & ATA_BM_STATUS_ERROR) != 0) {
775		FLOW("dma_finish: failed\n");
776		return B_ERROR;
777	}
778
779	FLOW("dma_finish leave\n");
780	return B_OK;
781}
782
783
784static int32
785handle_interrupt(void *arg)
786{
787	controller_data *controller = arg;
788	uint8 statusATA, statusBM;
789	int32 result;
790	int i;
791
792	FLOW("handle_interrupt\n");
793
794	result = B_UNHANDLED_INTERRUPT;
795
796	for (i = 0; i < controller->channel_count; i++) {
797		channel_data *channel = controller->channel[i];
798		if (!channel || channel->lost)
799			continue;
800
801		if (!channel->dma_active) {
802			// this could be a spurious interrupt, so read
803			// ata status register to acknowledge
804			*(channel->command_block + 7);
805			continue;
806		}
807
808		statusBM = *channel->bm_status_reg;
809		if (statusBM & ATA_BM_STATUS_INTERRUPT) {
810			statusATA = *(channel->command_block + 7);
811			*channel->bm_status_reg
812				= (statusBM & 0xf8) | ATA_BM_STATUS_INTERRUPT;
813			sATA->interrupt_handler(channel->ataChannel, statusATA);
814			result = B_INVOKE_SCHEDULER;
815		}
816	}
817
818	return result;
819}
820
821
822module_dependency module_dependencies[] = {
823	{ ATA_FOR_CONTROLLER_MODULE_NAME,	(module_info **)&sATA },
824	{ B_DEVICE_MANAGER_MODULE_NAME,		(module_info **)&sDeviceManager },
825	{ ATA_ADAPTER_MODULE_NAME,			(module_info **)&sATAAdapter },
826	{}
827};
828
829
830static ata_controller_interface sChannelInterface = {
831	{
832		{
833			CHANNEL_MODULE_NAME,
834			0,
835			NULL
836		},
837
838		.supports_device			= NULL,
839		.register_device			= NULL,
840		.init_driver				= &channel_init,
841		.uninit_driver				= &channel_uninit,
842		.register_child_devices		= NULL,
843		.device_removed				= &channel_removed,
844	},
845
846	.set_channel					= &set_channel,
847	.write_command_block_regs		= &task_file_write,
848	.read_command_block_regs		= &task_file_read,
849	.get_altstatus					= &altstatus_read,
850	.write_device_control			= &device_control_write,
851	.write_pio						= &pio_write,
852	.read_pio						= &pio_read,
853	.prepare_dma					= &dma_prepare,
854	.start_dma						= &dma_start,
855	.finish_dma						= &dma_finish,
856};
857
858
859static driver_module_info sControllerInterface = {
860	{
861		CONTROLLER_MODULE_NAME,
862		0,
863		NULL
864	},
865
866	.supports_device				= &controller_supports,
867	.register_device				= &controller_probe,
868	.init_driver					= &controller_init,
869	.uninit_driver					= &controller_uninit,
870	.register_child_devices			= &controller_register_channels,
871	.device_removed					= &controller_removed,
872};
873
874module_info *modules[] = {
875	(module_info *)&sControllerInterface,
876	(module_info *)&sChannelInterface,
877	NULL
878};
879