2 * Copyright 2006, Marcus Overhagen. All rights reserved.
3 * Distributed under the terms of the MIT License.
9 #include <KernelExport.h>
10 #include <device_manager.h>
13 #include <ide_adapter.h>
15 #define TRACE(x...) dprintf("si-3112: " x)
16 //#define FLOW(x...) dprintf("si-3112: " x)
20 #define DRIVER_PRETTY_NAME "Silicon Image SATA"
21 #define CONTROLLER_NAME DRIVER_PRETTY_NAME
22 #define CONTROLLER_MODULE_NAME "busses/ide/silicon_image_3112/driver_v1"
23 #define CHANNEL_MODULE_NAME "busses/ide/silicon_image_3112/channel/v1"
31 static const char *adapter_asic_names
[] = {
53 } kControllerChannelData
[] = {
54 { 0x80, 0x8A, 0x00, 0x148, 0xA0, "Primary Channel" },
55 { 0xC0, 0xCA, 0x08, 0x1C8, 0xE0, "Secondary Channel" },
56 { 0x280, 0x28A, 0x200, 0x348, 0x2A0, "Tertiary Channel" },
57 { 0x2C0, 0x2CA, 0x208, 0x3C8, 0x2E0, "Quaternary Channel" },
60 #define SI_SYSCFG 0x48
61 #define SI_BMDMA2 0x200
62 #define SI_INT_STEERING 0x02
63 #define SI_MASK_2PORT ((1 << 22) | (1 << 23))
64 #define SI_MASK_4PORT ((1 << 22) | (1 << 23) | (1 << 24) | (1 << 25))
68 typedef struct controller_data
{
69 pci_device_module_info
*pci
;
74 struct channel_data
*channel
[4]; // XXX only for interrupt workaround
75 int channel_count
; // XXX only for interrupt workaround
83 uint32 lost
; // != 0 if device got removed, i.e. if it must not
84 // be accessed anymore
88 typedef struct channel_data
{
89 pci_device_module_info
*pci
;
92 ide_channel ide_channel
;
94 volatile uint8
* task_file
;
95 volatile uint8
* control_block
;
96 volatile uint8
* command_block
;
97 volatile uint8
* dev_ctrl
;
98 volatile uint8
* bm_status_reg
;
99 volatile uint8
* bm_command_reg
;
100 volatile uint32
* bm_prdt_address
;
102 volatile uint32
* stat
;
106 phys_addr_t prdt_phys
;
112 static ide_for_controller_interface
* ide
;
113 static ide_adapter_interface
* ide_adapter
;
114 static device_manager_info
* dm
;
116 static status_t
device_control_write(void *channel_cookie
, uint8 val
);
117 static int32
handle_interrupt(void *arg
);
121 controller_supports(device_node
*parent
)
127 // get the bus (should be PCI)
128 if (dm
->get_attr_string(parent
, B_DEVICE_BUS
, &bus
, false) != B_OK
129 || strcmp(bus
, "pci") != 0)
132 // get vendor and device ID
133 if (dm
->get_attr_uint16(parent
, B_DEVICE_VENDOR_ID
, &vendorID
, false) != B_OK
134 || dm
->get_attr_uint16(parent
, B_DEVICE_ID
, &deviceID
, false) != B_OK
) {
138 #define ID(v, d) (((v) << 16) | (d))
139 switch (ID(vendorID
, deviceID
)) {
140 case ID(0x1095, 0x0240):
141 case ID(0x1095, 0x3112):
142 case ID(0x1095, 0x3114):
143 case ID(0x1095, 0x3512):
144 case ID(0x1002, 0x436e): // ATI
145 case ID(0x1002, 0x4379): // ATI
146 case ID(0x1002, 0x437a): // ATI
152 TRACE("controller found! vendor 0x%04x, device 0x%04x\n", vendorID
, deviceID
);
159 controller_probe(device_node
*parent
)
162 pci_device_module_info
*pci
;
166 uint8 interruptNumber
;
169 TRACE("controller_probe\n");
171 dm
->get_driver(parent
, (driver_module_info
**)&pci
, (void **)&device
);
173 deviceID
= pci
->read_pci_config(device
, PCI_device_id
, 2);
174 vendorID
= pci
->read_pci_config(device
, PCI_vendor_id
, 2);
175 interruptNumber
= pci
->read_pci_config(device
, PCI_interrupt_line
, 1);
176 mmioBase
= pci
->read_pci_config(device
, PCI_base_registers
+ 20, 4)
177 & PCI_address_io_mask
;
179 switch (ID(vendorID
, deviceID
)) {
180 case ID(0x1095, 0x0240):
181 case ID(0x1095, 0x3112):
182 case ID(0x1095, 0x3512):
183 case ID(0x1002, 0x436e): // ATI
184 case ID(0x1002, 0x4379): // ATI
185 case ID(0x1002, 0x437a): // ATI
186 asicIndex
= ASIC_SI3112
;
188 case ID(0x1095, 0x3114):
189 asicIndex
= ASIC_SI3114
;
192 TRACE("unsupported asic\n");
197 TRACE("mmio not configured\n");
201 if (interruptNumber
== 0 || interruptNumber
== 0xff) {
202 TRACE("irq not configured\n");
207 io_resource resources
[2] = {
208 { B_IO_MEMORY
, mmioBase
, kASICData
[asicIndex
].mmio_bar_size
},
211 device_attr attrs
[] = {
212 // properties of this controller for ide bus manager
213 // there are always max. 2 devices
214 // (unless this is a Compact Flash Card with a built-in IDE controller,
215 // which has exactly 1 device)
216 { IDE_CONTROLLER_MAX_DEVICES_ITEM
, B_UINT8_TYPE
, { ui8
: kASICData
[asicIndex
].channel_count
}},
217 // of course we can DMA
218 { IDE_CONTROLLER_CAN_DMA_ITEM
, B_UINT8_TYPE
, { ui8
: true }},
219 // command queuing always works
220 { IDE_CONTROLLER_CAN_CQ_ITEM
, B_UINT8_TYPE
, { ui8
: true }},
221 // choose any name here
222 { IDE_CONTROLLER_CONTROLLER_NAME_ITEM
, B_STRING_TYPE
, { string
: CONTROLLER_NAME
}},
225 // data must be word-aligned;
226 // warning: some controllers are more picky!
227 { B_DMA_ALIGNMENT
, B_UINT32_TYPE
, { ui32
: 1}},
228 // one S/G block must not cross 64K boundary
229 { B_DMA_BOUNDARY
, B_UINT32_TYPE
, { ui32
: 0xffff }},
230 // max size of S/G block is 16 bits with zero being 64K
231 { B_DMA_MAX_SEGMENT_BLOCKS
, B_UINT32_TYPE
, { ui32
: 0x10000 }},
232 { B_DMA_MAX_SEGMENT_COUNT
, B_UINT32_TYPE
,
233 { ui32
: IDE_ADAPTER_MAX_SG_COUNT
}},
234 { B_DMA_HIGH_ADDRESS
, B_UINT64_TYPE
, { ui64
: 0x100000000LL
}},
236 // private data to find controller
237 { "silicon_image_3112/asic_index", B_UINT32_TYPE
, { ui32
: asicIndex
}},
238 { "silicon_image_3112/mmio_base", B_UINT32_TYPE
, { ui32
: mmioBase
}},
239 { "silicon_image_3112/int_num", B_UINT32_TYPE
, { ui32
: interruptNumber
}},
243 TRACE("publishing controller\n");
245 return dm
->register_node(parent
, CONTROLLER_MODULE_NAME
, attrs
,
252 controller_init(device_node
*node
, void **_controllerCookie
)
254 controller_data
*controller
;
256 pci_device_module_info
*pci
;
262 uint32 interruptNumber
;
267 TRACE("controller_init\n");
269 if (dm
->get_attr_uint32(node
, "silicon_image_3112/asic_index", &asicIndex
, false) != B_OK
)
271 if (dm
->get_attr_uint32(node
, "silicon_image_3112/mmio_base", &mmioBase
, false) != B_OK
)
273 if (dm
->get_attr_uint32(node
, "silicon_image_3112/int_num", &interruptNumber
, false) != B_OK
)
276 controller
= malloc(sizeof(controller_data
));
280 FLOW("controller %p\n", controller
);
282 mmioArea
= map_physical_memory("Silicon Image SATA regs", mmioBase
,
283 kASICData
[asicIndex
].mmio_bar_size
, B_ANY_KERNEL_ADDRESS
, 0,
285 if (mmioArea
< B_OK
) {
286 TRACE("controller_init: mapping memory failed\n");
291 parent
= dm
->get_parent_node(node
);
292 dm
->get_driver(parent
, (driver_module_info
**)&pci
, (void **)&device
);
293 dm
->put_node(parent
);
295 TRACE("asic %ld\n", asicIndex
);
296 TRACE("int_num %ld\n", interruptNumber
);
297 TRACE("mmio_addr %p\n", (void *)mmioAddr
);
299 controller
->pci
= pci
;
300 controller
->device
= device
;
301 controller
->node
= node
;
302 controller
->asic_index
= asicIndex
;
303 controller
->int_num
= interruptNumber
;
304 controller
->mmio_area
= mmioArea
;
305 controller
->mmio_addr
= mmioAddr
;
306 controller
->lost
= 0;
308 controller
->channel_count
= kASICData
[asicIndex
].channel_count
;
309 for (i
= 0; i
< kASICData
[asicIndex
].channel_count
; i
++)
310 controller
->channel
[i
] = 0;
312 if (asicIndex
== ASIC_SI3114
) {
313 // I put a magic spell on you
314 temp
= *(volatile uint32
*)(mmioAddr
+ SI_BMDMA2
);
315 *(volatile uint32
*)(mmioAddr
+ SI_BMDMA2
) = temp
| SI_INT_STEERING
;
316 *(volatile uint32
*)(mmioAddr
+ SI_BMDMA2
); // flush
319 // disable all sata phy interrupts
320 for (i
= 0; i
< kASICData
[asicIndex
].channel_count
; i
++)
321 *(volatile uint32
*)(mmioAddr
+ kControllerChannelData
[i
].sien
) = 0;
322 *(volatile uint32
*)(mmioAddr
+ kControllerChannelData
[0].sien
); // flush
324 // install interrupt handler
325 res
= install_io_interrupt_handler(interruptNumber
, handle_interrupt
,
328 TRACE("controller_init: installing interrupt handler failed\n");
329 delete_area(mmioArea
);
335 temp
= *(volatile uint32
*)(mmioAddr
+ SI_SYSCFG
);
336 temp
&= (asicIndex
== ASIC_SI3114
) ? (~SI_MASK_4PORT
) : (~SI_MASK_2PORT
);
337 *(volatile uint32
*)(mmioAddr
+ SI_SYSCFG
) = temp
;
338 *(volatile uint32
*)(mmioAddr
+ SI_SYSCFG
); // flush
340 *_controllerCookie
= controller
;
342 TRACE("controller_init success\n");
348 controller_uninit(void *controllerCookie
)
350 controller_data
*controller
= controllerCookie
;
353 TRACE("controller_uninit enter\n");
355 // disable interrupts
356 temp
= *(volatile uint32
*)(controller
->mmio_addr
+ SI_SYSCFG
);
357 temp
|= (controller
->asic_index
== ASIC_SI3114
) ? SI_MASK_4PORT
: SI_MASK_2PORT
;
358 *(volatile uint32
*)(controller
->mmio_addr
+ SI_SYSCFG
) = temp
;
359 *(volatile uint32
*)(controller
->mmio_addr
+ SI_SYSCFG
); // flush
361 remove_io_interrupt_handler(controller
->int_num
, handle_interrupt
,
364 delete_area(controller
->mmio_area
);
367 TRACE("controller_uninit leave\n");
372 controller_register_channels(void *cookie
)
374 controller_data
*controller
= cookie
;
377 // publish channel nodes
378 for (index
= 0; index
< kASICData
[controller
->asic_index
].channel_count
;
380 device_attr attrs
[] = {
381 { B_DEVICE_PRETTY_NAME
, B_STRING_TYPE
, { string
: DRIVER_PRETTY_NAME
}},
382 // { PNP_DRIVER_CONNECTION, B_STRING_TYPE, { string: kControllerChannelData[channelIndex].name }},
383 { B_DEVICE_FIXED_CHILD
, B_STRING_TYPE
, { string
: IDE_FOR_CONTROLLER_MODULE_NAME
}},
385 // private data to identify channel
386 { IDE_CONTROLLER_CAN_DMA_ITEM
, B_UINT8_TYPE
, { ui8
: true }},
387 { "silicon_image_3112/chan_index", B_UINT32_TYPE
, { ui32
: index
}},
391 TRACE("publishing %s\n", kControllerChannelData
[index
].name
);
393 dm
->register_node(controller
->node
, CHANNEL_MODULE_NAME
, attrs
,
402 controller_removed(void *controllerCookie
)
404 controller_data
*controller
= controllerCookie
;
405 controller
->lost
= 1;
413 channel_init(device_node
*node
, void **_channelCookie
)
415 controller_data
*controller
;
417 channel_data
*channel
;
418 physical_entry entry
;
422 TRACE("channel_init enter\n");
424 channel
= malloc(sizeof(channel_data
));
428 if (dm
->get_attr_uint32(node
, "silicon_image_3112/chan_index", &channelIndex
, false) != B_OK
)
433 uint8 bus
, device
, function
;
434 uint16 vendorID
, deviceID
;
435 dm
->get_attr_uint8(node
, PCI_DEVICE_BUS_ITEM
, &bus
, true);
436 dm
->get_attr_uint8(node
, PCI_DEVICE_DEVICE_ITEM
, &device
, true);
437 dm
->get_attr_uint8(node
, PCI_DEVICE_FUNCTION_ITEM
, &function
, true);
438 dm
->get_attr_uint16(node
, PCI_DEVICE_VENDOR_ID_ITEM
, &vendorID
, true);
439 dm
->get_attr_uint16(node
, PCI_DEVICE_DEVICE_ID_ITEM
, &deviceID
, true);
440 TRACE("bus %3d, device %2d, function %2d: vendor %04x, device %04x\n",
441 bus
, device
, function
, vendorID
, deviceID
);
445 TRACE("channel_index %ld\n", channelIndex
);
446 TRACE("channel name: %s\n", kControllerChannelData
[channelIndex
].name
);
448 TRACE("channel %p\n", channel
);
450 parent
= dm
->get_parent_node(node
);
451 dm
->get_driver(parent
, NULL
, (void **)&controller
);
452 dm
->put_node(parent
);
454 TRACE("controller %p\n", controller
);
455 TRACE("mmio_addr %p\n", (void *)controller
->mmio_addr
);
457 // PRDT must be contiguous, dword-aligned and must not cross 64K boundary
458 // TODO: Where's the handling for the 64 K boundary? create_area_etc() can be
460 prdtSize
= (IDE_ADAPTER_MAX_SG_COUNT
* sizeof(prd_entry
) + (B_PAGE_SIZE
- 1)) & ~(B_PAGE_SIZE
- 1);
461 channel
->prd_area
= create_area("prd", (void **)&channel
->prdt
,
462 B_ANY_KERNEL_ADDRESS
, prdtSize
, B_32_BIT_CONTIGUOUS
, 0);
463 if (channel
->prd_area
< B_OK
) {
464 TRACE("creating prd_area failed\n");
468 get_memory_map(channel
->prdt
, prdtSize
, &entry
, 1);
469 channel
->prdt_phys
= entry
.address
;
471 channel
->pci
= controller
->pci
;
472 channel
->device
= controller
->device
;
473 channel
->node
= node
;
474 channel
->ide_channel
= NULL
;
476 channel
->task_file
= (volatile uint8
*)(controller
->mmio_addr
+ kControllerChannelData
[channelIndex
].cmd
+ 1);
477 channel
->control_block
= (volatile uint8
*)(controller
->mmio_addr
+ kControllerChannelData
[channelIndex
].ctl
);
478 channel
->command_block
= (volatile uint8
*)(controller
->mmio_addr
+ kControllerChannelData
[channelIndex
].cmd
);
479 channel
->dev_ctrl
= (volatile uint8
*)(controller
->mmio_addr
+ kControllerChannelData
[channelIndex
].ctl
);
480 channel
->bm_prdt_address
= (volatile uint32
*)(controller
->mmio_addr
+ kControllerChannelData
[channelIndex
].bmdma
+ IDE_BM_PRDT_ADDRESS
);
481 channel
->bm_status_reg
= (volatile uint8
*)(controller
->mmio_addr
+ kControllerChannelData
[channelIndex
].bmdma
+ IDE_BM_STATUS_REG
);
482 channel
->bm_command_reg
= (volatile uint8
*)(controller
->mmio_addr
+ kControllerChannelData
[channelIndex
].bmdma
+ IDE_BM_COMMAND_REG
);
483 channel
->stat
= (volatile uint32
*)(controller
->mmio_addr
+ kControllerChannelData
[channelIndex
].stat
);
486 channel
->dma_active
= 0;
488 controller
->channel
[channelIndex
] = channel
;
490 // enable interrupts so the channel is ready to run
491 device_control_write(channel
, ide_devctrl_bit3
);
493 *_channelCookie
= channel
;
495 TRACE("channel_init leave\n");
505 channel_uninit(void *channelCookie
)
507 channel_data
*channel
= channelCookie
;
509 TRACE("channel_uninit enter\n");
512 device_control_write(channel
, ide_devctrl_bit3
| ide_devctrl_nien
);
514 // catch spurious interrupt
515 // (some controllers generate an IRQ when you _disable_ interrupts,
516 // they are delayed by less then 40 µs, so 1 ms is safe)
519 delete_area(channel
->prd_area
);
522 TRACE("channel_uninit leave\n");
527 channel_removed(void *channelCookie
)
529 channel_data
*channel
= channelCookie
;
535 set_channel(void *channelCookie
, ide_channel ideChannel
)
537 channel_data
*channel
= channelCookie
;
538 channel
->ide_channel
= ideChannel
;
543 task_file_write(void *channelCookie
, ide_task_file
*tf
, ide_reg_mask mask
)
545 channel_data
*channel
= channelCookie
;
548 FLOW("task_file_write\n");
553 for (i
= 0; i
< 7; i
++) {
554 if( ((1 << (i
+7)) & mask
) != 0 ) {
555 FLOW("%x->HI(%x)\n", tf
->raw
.r
[i
+ 7], i
);
556 channel
->task_file
[i
] = tf
->raw
.r
[i
+ 7];
559 if (((1 << i
) & mask
) != 0) {
560 FLOW("%x->LO(%x)\n", tf
->raw
.r
[i
], i
);
561 channel
->task_file
[i
] = tf
->raw
.r
[i
];
564 *channel
->dev_ctrl
; // read altstatus to flush
571 task_file_read(void *channelCookie
, ide_task_file
*tf
, ide_reg_mask mask
)
573 channel_data
*channel
= channelCookie
;
576 FLOW("task_file_read\n");
581 for (i
= 0; i
< 7; i
++) {
582 if (((1 << i
) & mask
) != 0) {
583 tf
->raw
.r
[i
] = channel
->task_file
[i
];
584 FLOW("%x: %x\n", i
, (int)tf
->raw
.r
[i
] );
593 altstatus_read(void *channelCookie
)
595 channel_data
*channel
= channelCookie
;
597 FLOW("altstatus_read\n");
600 return 0x01; // Error bit
602 return *channel
->dev_ctrl
;
607 device_control_write(void *channelCookie
, uint8 val
)
609 channel_data
*channel
= channelCookie
;
611 FLOW("device_control_write 0x%x\n", val
);
616 *channel
->dev_ctrl
= val
;
617 *channel
->dev_ctrl
; // read altstatus to flush
624 pio_write(void *channelCookie
, uint16
*data
, int count
, bool force_16bit
)
626 channel_data
*channel
= channelCookie
;
630 FLOW("pio_write force_16bit = %d, (count & 1) = %d\n", force_16bit
, (count
& 1));
632 // The data port is only 8 bit wide in the command register block.
634 if ((count
& 1) != 0 || force_16bit
) {
635 volatile uint16
* base
= (volatile uint16
*)channel
->command_block
;
636 for ( ; count
> 0; --count
)
639 volatile uint32
* base
= (volatile uint32
*)channel
->command_block
;
640 uint32
*cur_data
= (uint32
*)data
;
642 for ( ; count
> 0; count
-= 2 )
643 *base
= *(cur_data
++);
645 *channel
->dev_ctrl
; // read altstatus to flush
652 pio_read(void *channelCookie
, uint16
*data
, int count
, bool force_16bit
)
654 channel_data
*channel
= channelCookie
;
658 FLOW("pio_read force_16bit = %d, (count & 1) = %d\n", force_16bit
, (count
& 1));
660 // The data port is only 8 bit wide in the command register block.
661 // We are memory mapped and read using 16 or 32 bit access from this 8 bit location.
663 if ((count
& 1) != 0 || force_16bit
) {
664 volatile uint16
* base
= (volatile uint16
*)channel
->command_block
;
665 for ( ; count
> 0; --count
)
668 volatile uint32
* base
= (volatile uint32
*)channel
->command_block
;
669 uint32
*cur_data
= (uint32
*)data
;
671 for ( ; count
> 0; count
-= 2 )
672 *(cur_data
++) = *base
;
680 dma_prepare(void *channelCookie
, const physical_entry
*sg_list
,
681 size_t sg_list_count
, bool write
)
683 channel_data
*channel
= channelCookie
;
684 pci_device_module_info
*pci
= channel
->pci
;
685 pci_device
*device
= channel
->device
;
686 prd_entry
*prd
= channel
->prdt
;
692 FLOW("dma_prepare enter\n");
694 for (i
= sg_list_count
- 1, prd
= channel
->prdt
; i
>= 0;
695 --i
, ++prd
, ++sg_list
) {
696 prd
->address
= B_HOST_TO_LENDIAN_INT32(pci
->ram_address(device
,
697 (void*)(addr_t
)sg_list
->address
));
699 // 0 means 64K - this is done automatically by discarding upper 16 bits
700 prd
->count
= B_HOST_TO_LENDIAN_INT16((uint16
)sg_list
->size
);
703 FLOW("%x, %x, %d\n", (int)prd
->address
, prd
->count
, prd
->EOT
);
706 // XXX move this to chan init?
707 temp
= (*channel
->bm_prdt_address
) & 3;
708 temp
|= B_HOST_TO_LENDIAN_INT32(pci
->ram_address(device
,
709 (void *)(addr_t
)channel
->prdt_phys
)) & ~3;
710 *channel
->bm_prdt_address
= temp
;
712 *channel
->dev_ctrl
; // read altstatus to flush
714 // reset interrupt and error signal
715 status
= *channel
->bm_status_reg
| IDE_BM_STATUS_INTERRUPT
716 | IDE_BM_STATUS_ERROR
;
717 *channel
->bm_status_reg
= status
;
719 *channel
->dev_ctrl
; // read altstatus to flush
721 // set data direction
722 command
= *channel
->bm_command_reg
;
724 command
&= ~IDE_BM_COMMAND_READ_FROM_DEVICE
;
726 command
|= IDE_BM_COMMAND_READ_FROM_DEVICE
;
728 *channel
->bm_command_reg
= command
;
730 *channel
->dev_ctrl
; // read altstatus to flush
732 FLOW("dma_prepare leave\n");
739 dma_start(void *channelCookie
)
741 channel_data
*channel
= channelCookie
;
744 FLOW("dma_start enter\n");
746 command
= *channel
->bm_command_reg
| IDE_BM_COMMAND_START_STOP
;
747 channel
->dma_active
= true;
748 *channel
->bm_command_reg
= command
;
750 *channel
->dev_ctrl
; // read altstatus to flush
752 FLOW("dma_start leave\n");
759 dma_finish(void *channelCookie
)
761 channel_data
*channel
= channelCookie
;
765 FLOW("dma_finish enter\n");
767 command
= *channel
->bm_command_reg
& ~IDE_BM_COMMAND_START_STOP
;
768 channel
->dma_active
= false;
770 *channel
->bm_command_reg
= command
;
772 status
= *channel
->bm_status_reg
;
774 *channel
->bm_status_reg
= status
| IDE_BM_STATUS_INTERRUPT
775 | IDE_BM_STATUS_ERROR
;
777 *channel
->dev_ctrl
; // read altstatus to flush
779 if ((status
& IDE_BM_STATUS_ERROR
) != 0) {
780 FLOW("dma_finish: failed\n");
784 if ((status
& IDE_BM_STATUS_INTERRUPT
) == 0) {
785 if ((status
& IDE_BM_STATUS_ACTIVE
) != 0) {
786 TRACE("dma_finish: transfer aborted\n");
789 TRACE("dma_finish: buffer underrun\n");
790 return B_DEV_DATA_UNDERRUN
;
793 if ((status
& IDE_BM_STATUS_ACTIVE
) != 0) {
794 TRACE("dma_finish: buffer too large\n");
795 return B_DEV_DATA_OVERRUN
;
797 FLOW("dma_finish leave\n");
805 handle_interrupt(void *arg
)
807 controller_data
*controller
= arg
;
812 // FLOW("handle_interrupt\n");
814 result
= B_UNHANDLED_INTERRUPT
;
816 for (i
= 0; i
< controller
->channel_count
; i
++) {
817 channel_data
*channel
= controller
->channel
[i
];
818 if (!channel
|| channel
->lost
)
821 if (channel
->dma_active
) {
822 if ((*channel
->bm_status_reg
& IDE_BM_STATUS_INTERRUPT
) == 0)
825 // for PIO, read the "Task File Configuration + Status" Interrupt
827 if (!(*channel
->stat
& (1 << 11)))
832 status
= *(channel
->command_block
+ 7);
833 ret
= ide
->irq_handler(channel
->ide_channel
, status
);
834 if (ret
== B_INVOKE_SCHEDULER
|| result
== B_UNHANDLED_INTERRUPT
)
842 module_dependency module_dependencies
[] = {
843 { IDE_FOR_CONTROLLER_MODULE_NAME
, (module_info
**)&ide
},
844 { B_DEVICE_MANAGER_MODULE_NAME
, (module_info
**)&dm
},
845 { IDE_ADAPTER_MODULE_NAME
, (module_info
**)&ide_adapter
},
850 static ide_controller_interface sChannelInterface
= {
858 .supports_device
= NULL
,
859 .register_device
= NULL
,
860 .init_driver
= &channel_init
,
861 .uninit_driver
= &channel_uninit
,
862 .register_child_devices
= NULL
,
863 .device_removed
= &channel_removed
,
866 .set_channel
= &set_channel
,
867 .write_command_block_regs
= &task_file_write
,
868 .read_command_block_regs
= &task_file_read
,
869 .get_altstatus
= &altstatus_read
,
870 .write_device_control
= &device_control_write
,
871 .write_pio
= &pio_write
,
872 .read_pio
= &pio_read
,
873 .prepare_dma
= &dma_prepare
,
874 .start_dma
= &dma_start
,
875 .finish_dma
= &dma_finish
,
879 static driver_module_info sControllerInterface
= {
881 CONTROLLER_MODULE_NAME
,
886 .supports_device
= &controller_supports
,
887 .register_device
= &controller_probe
,
888 .init_driver
= &controller_init
,
889 .uninit_driver
= &controller_uninit
,
890 .register_child_devices
= &controller_register_channels
,
891 .device_removed
= &controller_removed
,
894 module_info
*modules
[] = {
895 (module_info
*)&sControllerInterface
,
896 (module_info
*)&sChannelInterface
,