vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / busses / ata / silicon_image_3112 / silicon_image_3112.c
blob5a5993ef2e61c460842d5164245440a31db2bb89
1 /*
2 * Copyright 2006-2009, Marcus Overhagen. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
6 #include <KernelExport.h>
7 #include <stdlib.h>
8 #include <string.h>
10 #include <ata_adapter.h>
11 #include <tracing.h>
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...)
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"
23 enum asic_type {
24 ASIC_SI3112 = 0,
25 ASIC_SI3114 = 1,
28 static 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" },
37 static 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" },
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))
57 struct channel_data;
59 typedef struct controller_data {
60 pci_device_module_info *pci;
61 pci_device *device;
63 device_node *node;
65 struct channel_data *channel[4]; // XXX only for interrupt workaround
66 int channel_count; // XXX only for interrupt workaround
68 uint32 asic_index;
69 uint32 int_num;
71 area_id mmio_area;
72 addr_t mmio_addr;
74 uint32 lost; // != 0 if device got removed, i.e. if it must not
75 // be accessed anymore
76 } controller_data;
79 typedef struct channel_data {
80 pci_device_module_info *pci;
81 device_node * node;
82 pci_device * device;
83 ata_channel ataChannel;
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;
93 volatile uint32 * stat;
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;
103 static ata_for_controller_interface* sATA;
104 static ata_adapter_interface* sATAAdapter;
105 static device_manager_info* sDeviceManager;
107 static status_t device_control_write(void *channel_cookie, uint8 val);
108 static int32 handle_interrupt(void *arg);
111 static float
112 controller_supports(device_node *parent)
114 const char *bus;
115 uint16 vendorID;
116 uint16 deviceID;
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;
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;
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;
143 TRACE("controller found! vendor 0x%04x, device 0x%04x\n", vendorID, deviceID);
145 return 0.8f;
149 static status_t
150 controller_probe(device_node *parent)
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;
160 TRACE("controller_probe\n");
162 sDeviceManager->get_driver(parent, (driver_module_info **)&pci, (void **)&device);
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;
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;
187 if (!mmioBase) {
188 TRACE("mmio not configured\n");
189 return B_ERROR;
192 if (interruptNumber == 0 || interruptNumber == 0xff) {
193 TRACE("irq not configured\n");
194 return B_ERROR;
198 io_resource resources[2] = {
199 { B_IO_MEMORY, mmioBase, kASICData[asicIndex].mmio_bar_size },
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 }},
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 }},
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 }
237 TRACE("publishing controller\n");
239 return sDeviceManager->register_node(parent, CONTROLLER_MODULE_NAME, attrs,
240 resources, NULL);
245 static status_t
246 controller_init(device_node *node, void **_controllerCookie)
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;
261 TRACE("controller_init\n");
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;
270 controller = malloc(sizeof(controller_data));
271 if (!controller)
272 return B_NO_MEMORY;
274 FLOW("controller %p\n", controller);
276 mmioArea = map_physical_memory("Silicon Image SATA regs", mmioBase,
277 kASICData[asicIndex].mmio_bar_size, B_ANY_KERNEL_ADDRESS, 0,
278 (void **)&mmioAddr);
279 if (mmioArea < B_OK) {
280 TRACE("controller_init: mapping memory failed\n");
281 free(controller);
282 return B_ERROR;
285 parent = sDeviceManager->get_parent_node(node);
286 sDeviceManager->get_driver(parent, (driver_module_info **)&pci, (void **)&device);
287 sDeviceManager->put_node(parent);
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);
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;
303 controller->channel_count = kASICData[asicIndex].channel_count;
304 for (i = 0; i < kASICData[asicIndex].channel_count; i++)
305 controller->channel[i] = 0;
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
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
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;
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
335 *_controllerCookie = controller;
337 TRACE("controller_init success\n");
338 return B_OK;
342 static void
343 controller_uninit(void *controllerCookie)
345 controller_data *controller = controllerCookie;
346 uint32 temp;
348 TRACE("controller_uninit enter\n");
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
356 remove_io_interrupt_handler(controller->int_num, handle_interrupt,
357 controller);
359 delete_area(controller->mmio_area);
360 free(controller);
362 TRACE("controller_uninit leave\n");
366 static status_t
367 controller_register_channels(void *cookie)
369 controller_data *controller = cookie;
370 int index;
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 }},
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 }
386 TRACE("publishing %s\n", kControllerChannelData[index].name);
388 sDeviceManager->register_node(controller->node, CHANNEL_MODULE_NAME, attrs,
389 NULL, NULL);
392 return B_OK;
396 static void
397 controller_removed(void *controllerCookie)
399 controller_data *controller = controllerCookie;
400 controller->lost = 1;
404 // #pragma mark -
407 static status_t
408 channel_init(device_node *node, void **_channelCookie)
410 controller_data *controller;
411 device_node *parent;
412 channel_data *channel;
413 physical_entry entry;
414 size_t prdtSize;
415 uint32 channelIndex;
417 TRACE("channel_init enter\n");
419 channel = malloc(sizeof(channel_data));
420 if (!channel)
421 return B_NO_MEMORY;
423 if (sDeviceManager->get_attr_uint32(node, "silicon_image_3112/chan_index", &channelIndex, false) != B_OK)
424 goto err;
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);
438 #endif
440 TRACE("channel_index %" B_PRId32 "\n", channelIndex);
441 TRACE("channel name: %s\n", kControllerChannelData[channelIndex].name);
443 TRACE("channel %p\n", channel);
445 parent = sDeviceManager->get_parent_node(node);
446 sDeviceManager->get_driver(parent, NULL, (void **)&controller);
447 sDeviceManager->put_node(parent);
449 TRACE("controller %p\n", controller);
450 TRACE("mmio_addr %p\n", (void *)controller->mmio_addr);
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, 0);
458 if (channel->prd_area < B_OK) {
459 TRACE("creating prd_area failed\n");
460 goto err;
463 get_memory_map(channel->prdt, prdtSize, &entry, 1);
464 channel->prdt_phys = entry.address;
466 channel->pci = controller->pci;
467 channel->device = controller->device;
468 channel->node = node;
469 channel->ataChannel = NULL;
471 channel->task_file = (volatile uint8 *)(controller->mmio_addr + kControllerChannelData[channelIndex].cmd + 1);
472 channel->control_block = (volatile uint8 *)(controller->mmio_addr + kControllerChannelData[channelIndex].ctl);
473 channel->command_block = (volatile uint8 *)(controller->mmio_addr + kControllerChannelData[channelIndex].cmd);
474 channel->dev_ctrl = (volatile uint8 *)(controller->mmio_addr + kControllerChannelData[channelIndex].ctl);
475 channel->bm_prdt_address = (volatile uint32 *)(controller->mmio_addr + kControllerChannelData[channelIndex].bmdma + ATA_BM_PRDT_ADDRESS);
476 channel->bm_status_reg = (volatile uint8 *)(controller->mmio_addr + kControllerChannelData[channelIndex].bmdma + ATA_BM_STATUS_REG);
477 channel->bm_command_reg = (volatile uint8 *)(controller->mmio_addr + kControllerChannelData[channelIndex].bmdma + ATA_BM_COMMAND_REG);
478 channel->stat = (volatile uint32 *)(controller->mmio_addr + kControllerChannelData[channelIndex].stat);
480 channel->lost = 0;
481 channel->dma_active = 0;
483 controller->channel[channelIndex] = channel;
485 // disable interrupts
486 device_control_write(channel, ATA_DEVICE_CONTROL_BIT3
487 | ATA_DEVICE_CONTROL_DISABLE_INTS);
489 *_channelCookie = channel;
491 TRACE("channel_init leave\n");
492 return B_OK;
494 err:
495 free(channel);
496 return B_ERROR;
500 static void
501 channel_uninit(void *channelCookie)
503 channel_data *channel = channelCookie;
505 TRACE("channel_uninit enter\n");
507 // disable interrupts
508 device_control_write(channel, ATA_DEVICE_CONTROL_BIT3
509 | ATA_DEVICE_CONTROL_DISABLE_INTS);
511 delete_area(channel->prd_area);
512 free(channel);
514 TRACE("channel_uninit leave\n");
518 static void
519 channel_removed(void *channelCookie)
521 channel_data *channel = channelCookie;
522 channel->lost = 1;
526 static void
527 set_channel(void *channelCookie, ata_channel ataChannel)
529 channel_data *channel = channelCookie;
530 channel->ataChannel = ataChannel;
534 static status_t
535 task_file_write(void *channelCookie, ata_task_file *tf, ata_reg_mask mask)
537 channel_data *channel = channelCookie;
538 int i;
540 FLOW("task_file_write\n");
542 if (channel->lost)
543 return B_ERROR;
545 for (i = 0; i < 7; i++) {
546 if( ((1 << (i+7)) & mask) != 0 ) {
547 FLOW("%x->HI(%x)\n", tf->raw.r[i + 7], i );
548 channel->task_file[i] = tf->raw.r[i + 7];
551 if (((1 << i) & mask) != 0) {
552 FLOW("%x->LO(%x)\n", tf->raw.r[i], i );
553 channel->task_file[i] = tf->raw.r[i];
556 *channel->dev_ctrl; // read altstatus to flush
558 return B_OK;
562 static status_t
563 task_file_read(void *channelCookie, ata_task_file *tf, ata_reg_mask mask)
565 channel_data *channel = channelCookie;
566 int i;
568 FLOW("task_file_read\n");
570 if (channel->lost)
571 return B_ERROR;
573 for (i = 0; i < 7; i++) {
574 if (((1 << i) & mask) != 0) {
575 tf->raw.r[i] = channel->task_file[i];
576 FLOW("%x: %x\n", i, (int)tf->raw.r[i] );
580 return B_OK;
584 static uint8
585 altstatus_read(void *channelCookie)
587 channel_data *channel = channelCookie;
589 FLOW("altstatus_read\n");
591 if (channel->lost)
592 return 0x01; // Error bit
594 return *channel->dev_ctrl;
598 static status_t
599 device_control_write(void *channelCookie, uint8 val)
601 channel_data *channel = channelCookie;
603 FLOW("device_control_write 0x%x\n", val);
605 if (channel->lost)
606 return B_ERROR;
608 *channel->dev_ctrl = val;
609 *channel->dev_ctrl; // read altstatus to flush
611 return B_OK;
615 static status_t
616 pio_write(void *channelCookie, uint16 *data, int count, bool force_16bit)
618 channel_data *channel = channelCookie;
619 if (channel->lost)
620 return B_ERROR;
622 FLOW("pio_write force_16bit = %d, (count & 1) = %d\n", force_16bit, (count & 1));
624 // The data port is only 8 bit wide in the command register block.
626 if ((count & 1) != 0 || force_16bit) {
627 volatile uint16 * base = (volatile uint16 *)channel->command_block;
628 for ( ; count > 0; --count)
629 *base = *(data++);
630 } else {
631 volatile uint32 * base = (volatile uint32 *)channel->command_block;
632 uint32 *cur_data = (uint32 *)data;
634 for ( ; count > 0; count -= 2 )
635 *base = *(cur_data++);
637 *channel->dev_ctrl; // read altstatus to flush
639 return B_OK;
643 static status_t
644 pio_read(void *channelCookie, uint16 *data, int count, bool force_16bit)
646 channel_data *channel = channelCookie;
647 if (channel->lost)
648 return B_ERROR;
650 FLOW("pio_read force_16bit = %d, (count & 1) = %d\n", force_16bit, (count & 1));
652 // The data port is only 8 bit wide in the command register block.
653 // We are memory mapped and read using 16 or 32 bit access from this 8 bit location.
655 if ((count & 1) != 0 || force_16bit) {
656 volatile uint16 * base = (volatile uint16 *)channel->command_block;
657 for ( ; count > 0; --count)
658 *(data++) = *base;
659 } else {
660 volatile uint32 * base = (volatile uint32 *)channel->command_block;
661 uint32 *cur_data = (uint32 *)data;
663 for ( ; count > 0; count -= 2 )
664 *(cur_data++) = *base;
667 return B_OK;
671 static status_t
672 dma_prepare(void *channelCookie, const physical_entry *sg_list,
673 size_t sg_list_count, bool write)
675 channel_data *channel = channelCookie;
676 pci_device_module_info *pci = channel->pci;
677 pci_device *device = channel->device;
678 prd_entry *prd = channel->prdt;
679 uint8 command;
680 uint8 status;
681 uint32 temp;
682 int i;
684 FLOW("dma_prepare enter\n");
686 for (i = sg_list_count - 1, prd = channel->prdt; i >= 0;
687 --i, ++prd, ++sg_list ) {
688 prd->address = B_HOST_TO_LENDIAN_INT32((uint32)pci->ram_address(device,
689 sg_list->address));
691 // 0 means 64K - this is done automatically by discarding upper 16 bits
692 prd->count = B_HOST_TO_LENDIAN_INT16((uint16)sg_list->size);
693 prd->EOT = i == 0;
695 FLOW("%" B_PRIx32", %" B_PRId16", %" B_PRId8"\n", prd->address, prd->count, prd->EOT);
698 // XXX move this to chan init?
699 temp = (*channel->bm_prdt_address) & 3;
700 temp |= B_HOST_TO_LENDIAN_INT32((uint32)pci->ram_address(device,
701 channel->prdt_phys)) & ~3;
702 *channel->bm_prdt_address = temp;
704 *channel->dev_ctrl; // read altstatus to flush
706 // reset interrupt and error signal
707 status = *channel->bm_status_reg | ATA_BM_STATUS_INTERRUPT
708 | ATA_BM_STATUS_ERROR;
709 *channel->bm_status_reg = status;
711 *channel->dev_ctrl; // read altstatus to flush
713 // set data direction
714 command = *channel->bm_command_reg;
715 if (write)
716 command &= ~ATA_BM_COMMAND_READ_FROM_DEVICE;
717 else
718 command |= ATA_BM_COMMAND_READ_FROM_DEVICE;
720 *channel->bm_command_reg = command;
722 *channel->dev_ctrl; // read altstatus to flush
724 FLOW("dma_prepare leave\n");
726 return B_OK;
730 static status_t
731 dma_start(void *channelCookie)
733 channel_data *channel = channelCookie;
734 uint8 command;
736 FLOW("dma_start enter\n");
738 command = *channel->bm_command_reg | ATA_BM_COMMAND_START_STOP;
739 channel->dma_active = true;
740 *channel->bm_command_reg = command;
742 *channel->dev_ctrl; // read altstatus to flush
744 FLOW("dma_start leave\n");
746 return B_OK;
750 static status_t
751 dma_finish(void *channelCookie)
753 channel_data *channel = channelCookie;
754 uint8 command;
755 uint8 status;
757 FLOW("dma_finish enter\n");
759 status = *channel->bm_status_reg;
761 command = *channel->bm_command_reg;
762 *channel->bm_command_reg = command & ~ATA_BM_COMMAND_START_STOP;
764 channel->dma_active = false;
766 *channel->bm_status_reg = status | ATA_BM_STATUS_ERROR;
767 *channel->dev_ctrl; // read altstatus to flush
769 if ((status & ATA_BM_STATUS_ACTIVE) != 0) {
770 TRACE("dma_finish: buffer too large\n");
771 return B_DEV_DATA_OVERRUN;
773 if ((status & ATA_BM_STATUS_ERROR) != 0) {
774 FLOW("dma_finish: failed\n");
775 return B_ERROR;
778 FLOW("dma_finish leave\n");
779 return B_OK;
783 static int32
784 handle_interrupt(void *arg)
786 controller_data *controller = arg;
787 uint8 statusATA, statusBM;
788 int32 result;
789 int i;
791 FLOW("handle_interrupt\n");
793 result = B_UNHANDLED_INTERRUPT;
795 for (i = 0; i < controller->channel_count; i++) {
796 channel_data *channel = controller->channel[i];
797 if (!channel || channel->lost)
798 continue;
800 if (!channel->dma_active) {
801 // this could be a spurious interrupt, so read
802 // ata status register to acknowledge
803 *(channel->command_block + 7);
804 continue;
807 statusBM = *channel->bm_status_reg;
808 if (statusBM & ATA_BM_STATUS_INTERRUPT) {
809 statusATA = *(channel->command_block + 7);
810 *channel->bm_status_reg
811 = (statusBM & 0xf8) | ATA_BM_STATUS_INTERRUPT;
812 sATA->interrupt_handler(channel->ataChannel, statusATA);
813 result = B_INVOKE_SCHEDULER;
817 return result;
821 module_dependency module_dependencies[] = {
822 { ATA_FOR_CONTROLLER_MODULE_NAME, (module_info **)&sATA },
823 { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&sDeviceManager },
824 { ATA_ADAPTER_MODULE_NAME, (module_info **)&sATAAdapter },
829 static ata_controller_interface sChannelInterface = {
832 CHANNEL_MODULE_NAME,
834 NULL
837 .supports_device = NULL,
838 .register_device = NULL,
839 .init_driver = &channel_init,
840 .uninit_driver = &channel_uninit,
841 .register_child_devices = NULL,
842 .device_removed = &channel_removed,
845 .set_channel = &set_channel,
846 .write_command_block_regs = &task_file_write,
847 .read_command_block_regs = &task_file_read,
848 .get_altstatus = &altstatus_read,
849 .write_device_control = &device_control_write,
850 .write_pio = &pio_write,
851 .read_pio = &pio_read,
852 .prepare_dma = &dma_prepare,
853 .start_dma = &dma_start,
854 .finish_dma = &dma_finish,
858 static driver_module_info sControllerInterface = {
860 CONTROLLER_MODULE_NAME,
862 NULL
865 .supports_device = &controller_supports,
866 .register_device = &controller_probe,
867 .init_driver = &controller_init,
868 .uninit_driver = &controller_uninit,
869 .register_child_devices = &controller_register_channels,
870 .device_removed = &controller_removed,
873 module_info *modules[] = {
874 (module_info *)&sControllerInterface,
875 (module_info *)&sChannelInterface,
876 NULL