/*
* ide_controller.c
*
* This is generic rtems driver for IDE controllers.
*
* Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
* Authors: Alexandra Kossovsky <sasha@oktet.ru>
* Eugeny S. Mints <Eugeny.Mints@oktet.ru>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
*/
#define IDE_CONTROLLER_TRACE 0
#include <rtems/chain.h>
#include <errno.h>
#include <rtems/blkdev.h>
#include <libchip/ide_ctrl.h>
#include <libchip/ide_ctrl_cfg.h>
#include <libchip/ide_ctrl_io.h>
#if IDE_CONTROLLER_TRACE
int ide_controller_trace = 1;
#endif
/*
* ide_controller_initialize --
* Initializes all configured IDE controllers. Controllers configuration
* table is provided by BSP
*
* PARAMETERS:
* major - device major number
* minor_arg - device minor number
* args - arguments
*
* RETURNS:
* RTEMS_SUCCESSFUL on success, or error code if
* error occured
*/
rtems_device_driver
ide_controller_initialize(rtems_device_major_number major,
rtems_device_minor_number minor_arg,
void *args)
{
unsigned long minor;
/* FIXME: may be it should be done on compilation phase */
if (IDE_Controller_Count > IDE_CTRL_MAX_MINOR_NUMBER)
rtems_fatal_error_occurred(RTEMS_TOO_MANY);
for (minor=0; minor < IDE_Controller_Count; minor++)
{
IDE_Controller_Table[minor].status = IDE_CTRL_NON_INITIALIZED;
if ((IDE_Controller_Table[minor].probe == NULL ||
IDE_Controller_Table[minor].probe(minor)) &&
(IDE_Controller_Table[minor].fns->ctrl_probe == NULL ||
IDE_Controller_Table[minor].fns->ctrl_probe(minor)))
{
dev_t dev;
dev = rtems_filesystem_make_dev_t( major, minor );
if (mknod(IDE_Controller_Table[minor].name,
0777 | S_IFBLK, dev ) < 0)
rtems_fatal_error_occurred(errno);
IDE_Controller_Table[minor].fns->ctrl_initialize(minor);
IDE_Controller_Table[minor].status = IDE_CTRL_INITIALIZED;
}
}
return RTEMS_SUCCESSFUL;
}
/*
* ide_controller_read_data_block --
* Read data block via controller's data register
*
* PARAMETERS:
* minor - minor number of controller
* block_size - number of bytes to read
* bufs - set of buffers to store data
* cbuf - number of current buffer from the set
* pos - position inside current buffer 'cbuf'
*
* RETURNS:
* NONE
*/
void
ide_controller_read_data_block(rtems_device_minor_number minor,
uint32_t block_size,
rtems_blkdev_sg_buffer *bufs,
uint32_t *cbuf,
uint32_t *pos)
{
#if IDE_CONTROLLER_TRACE
if (ide_controller_trace)
printk ("IDE data block read: %d:%d\n", *cbuf, bufs[*cbuf].block);
#endif
IDE_Controller_Table[minor].fns->ctrl_read_block(minor, block_size, bufs,
cbuf, pos);
}
/*
* ide_controller_write_data_block --
* Write data block via controller's data register
*
* PARAMETERS:
* minor - minor number of controller
* block_size - number of bytes to write
* bufs - set of buffers which store data
* cbuf - number of current buffer from the set
* pos - position inside current buffer 'cbuf'
*
* RETURNS:
* NONE
*/
void
ide_controller_write_data_block(rtems_device_minor_number minor,
uint32_t block_size,
rtems_blkdev_sg_buffer *bufs,
uint32_t *cbuf,
uint32_t *pos)
{
#if IDE_CONTROLLER_TRACE
if (ide_controller_trace)
printk ("IDE data block write: %d:%d\n", *cbuf, bufs[*cbuf].block);
#endif
IDE_Controller_Table[minor].fns->ctrl_write_block(minor, block_size, bufs,
cbuf, pos);
}
/*
* ide_controller_read_register --
* Read controller's register
*
* PARAMETERS:
* minor - minor number of controller
* reg - register to read
* value - placeholder for result
*
* RETURNS
* NONE
*/
void
ide_controller_read_register(rtems_device_minor_number minor,
int reg,
uint16_t *value)
{
IDE_Controller_Table[minor].fns->ctrl_reg_read(minor, reg, value);
#if IDE_CONTROLLER_TRACE
if (ide_controller_trace)
printk ("IDE read reg: %d => %04x\n", reg, *value);
#endif
}
/*
* ide_controller_write_register --
* Write controller's register
*
* PARAMETERS:
* minor - minor number of controller
* reg - register to write
* value - value to write
*
* RETURNS:
* NONE
*/
void
ide_controller_write_register(rtems_device_minor_number minor, int reg,
uint16_t value)
{
#if IDE_CONTROLLER_TRACE
if (ide_controller_trace)
printk ("IDE write reg: %d => %04x\n", reg, value);
#endif
IDE_Controller_Table[minor].fns->ctrl_reg_write(minor, reg, value);
}
/*
* ide_controller_config_io_speed --
* Set controller's speed of IO operations
*
* PARAMETERS:
* minor - minor number of controller
* modes_available - speeds available
*
* RETURNS:
* RTEMS_SUCCESSFUL on success, or error code if
* error occured
*/
rtems_status_code
ide_controller_config_io_speed(int minor, uint16_t modes_available)
{
return IDE_Controller_Table[minor].fns->ctrl_config_io_speed(
minor,
modes_available);
}