2 * Copyright 2006-2009, Marcus Overhagen. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 #include <KernelExport.h>
10 #include <ata_adapter.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)
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"
31 const char *asic_name
;
33 { 2, 0x200, "si3112" },
34 { 4, 0x400, "si3114" },
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))
59 typedef struct controller_data
{
60 pci_device_module_info
*pci
;
65 struct channel_data
*channel
[4]; // XXX only for interrupt workaround
66 int channel_count
; // XXX only for interrupt workaround
74 uint32 lost
; // != 0 if device got removed, i.e. if it must not
75 // be accessed anymore
79 typedef struct channel_data
{
80 pci_device_module_info
*pci
;
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
;
97 phys_addr_t prdt_phys
;
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
);
112 controller_supports(device_node
*parent
)
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)
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
) {
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
143 TRACE("controller found! vendor 0x%04x, device 0x%04x\n", vendorID
, deviceID
);
150 controller_probe(device_node
*parent
)
153 pci_device_module_info
*pci
;
157 uint8 interruptNumber
;
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
;
179 case ID(0x1095, 0x3114):
180 asicIndex
= ASIC_SI3114
;
183 TRACE("unsupported asic\n");
188 TRACE("mmio not configured\n");
192 if (interruptNumber
== 0 || interruptNumber
== 0xff) {
193 TRACE("irq not configured\n");
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
}},
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
,
232 { "silicon_image_3112/int_num", B_UINT32_TYPE
,
233 { ui32
: interruptNumber
}},
237 TRACE("publishing controller\n");
239 return sDeviceManager
->register_node(parent
, CONTROLLER_MODULE_NAME
, attrs
,
246 controller_init(device_node
*node
, void **_controllerCookie
)
248 controller_data
*controller
;
250 pci_device_module_info
*pci
;
256 uint32 interruptNumber
;
261 TRACE("controller_init\n");
263 if (sDeviceManager
->get_attr_uint32(node
, "silicon_image_3112/asic_index", &asicIndex
, false) != B_OK
)
265 if (sDeviceManager
->get_attr_uint32(node
, "silicon_image_3112/mmio_base", &mmioBase
, false) != B_OK
)
267 if (sDeviceManager
->get_attr_uint32(node
, "silicon_image_3112/int_num", &interruptNumber
, false) != B_OK
)
270 controller
= malloc(sizeof(controller_data
));
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,
279 if (mmioArea
< B_OK
) {
280 TRACE("controller_init: mapping memory failed\n");
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
,
323 TRACE("controller_init: installing interrupt handler failed\n");
324 delete_area(mmioArea
);
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");
343 controller_uninit(void *controllerCookie
)
345 controller_data
*controller
= controllerCookie
;
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
,
359 delete_area(controller
->mmio_area
);
362 TRACE("controller_uninit leave\n");
367 controller_register_channels(void *cookie
)
369 controller_data
*controller
= cookie
;
372 // publish channel nodes
373 for (index
= 0; index
< kASICData
[controller
->asic_index
].channel_count
;
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
}},
386 TRACE("publishing %s\n", kControllerChannelData
[index
].name
);
388 sDeviceManager
->register_node(controller
->node
, CHANNEL_MODULE_NAME
, attrs
,
397 controller_removed(void *controllerCookie
)
399 controller_data
*controller
= controllerCookie
;
400 controller
->lost
= 1;
408 channel_init(device_node
*node
, void **_channelCookie
)
410 controller_data
*controller
;
412 channel_data
*channel
;
413 physical_entry entry
;
417 TRACE("channel_init enter\n");
419 channel
= malloc(sizeof(channel_data
));
423 if (sDeviceManager
->get_attr_uint32(node
, "silicon_image_3112/chan_index", &channelIndex
, false) != B_OK
)
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
);
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
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");
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
);
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");
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
);
514 TRACE("channel_uninit leave\n");
519 channel_removed(void *channelCookie
)
521 channel_data
*channel
= channelCookie
;
527 set_channel(void *channelCookie
, ata_channel ataChannel
)
529 channel_data
*channel
= channelCookie
;
530 channel
->ataChannel
= ataChannel
;
535 task_file_write(void *channelCookie
, ata_task_file
*tf
, ata_reg_mask mask
)
537 channel_data
*channel
= channelCookie
;
540 FLOW("task_file_write\n");
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
563 task_file_read(void *channelCookie
, ata_task_file
*tf
, ata_reg_mask mask
)
565 channel_data
*channel
= channelCookie
;
568 FLOW("task_file_read\n");
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
] );
585 altstatus_read(void *channelCookie
)
587 channel_data
*channel
= channelCookie
;
589 FLOW("altstatus_read\n");
592 return 0x01; // Error bit
594 return *channel
->dev_ctrl
;
599 device_control_write(void *channelCookie
, uint8 val
)
601 channel_data
*channel
= channelCookie
;
603 FLOW("device_control_write 0x%x\n", val
);
608 *channel
->dev_ctrl
= val
;
609 *channel
->dev_ctrl
; // read altstatus to flush
616 pio_write(void *channelCookie
, uint16
*data
, int count
, bool force_16bit
)
618 channel_data
*channel
= channelCookie
;
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
)
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
644 pio_read(void *channelCookie
, uint16
*data
, int count
, bool force_16bit
)
646 channel_data
*channel
= channelCookie
;
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
)
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
;
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
;
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
,
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
);
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
;
716 command
&= ~ATA_BM_COMMAND_READ_FROM_DEVICE
;
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");
731 dma_start(void *channelCookie
)
733 channel_data
*channel
= channelCookie
;
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");
751 dma_finish(void *channelCookie
)
753 channel_data
*channel
= channelCookie
;
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");
778 FLOW("dma_finish leave\n");
784 handle_interrupt(void *arg
)
786 controller_data
*controller
= arg
;
787 uint8 statusATA
, statusBM
;
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
)
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);
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
;
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
= {
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
,
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
,