Ignore:
Timestamp:
Mar 27, 2015, 11:51:33 AM (10 years ago)
Author:
alain
Message:

1) Removing the IOC driver (integrated in the FAT library).
2) Simplifying the BDV, HBA, SDC, RDK drivers: they support
only two modes (synchronous => polling / descheduling => IRQ),
and only one access function (for both read/write).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_drivers/hba_driver.c

    r481 r529  
    1 ///////////////////////////////////////////////////////////////////////////////////
     1//////////////////////////////////////////////////////////////////////////////////
    22// File     : hba_driver.c
    33// Date     : 23/11/2013
     
    66///////////////////////////////////////////////////////////////////////////////////
    77// Implementation notes:
    8 // 1. In order to share code, the two _hba_read() and _hba_write() functions
    9 //    call the same _hba_set_cmd() function.
    10 // 2. All accesses to HBA registers are done by the two
    11 //    _hba_set_register() and _hba_get_register() low-level functions,
    12 //    that are handling virtual / physical extended addressing.
     8// All accesses to HBA registers are done by the two
     9// _hba_set_register() and _hba_get_register() low-level functions,
     10// that are handling virtual / physical extended addressing.
    1311///////////////////////////////////////////////////////////////////////////////////
    1412
    1513#include <giet_config.h>
    16 #include <ioc_driver.h>
     14#include <hard_config.h>
     15#include <hba_driver.h>
     16#include <xcu_driver.h>
     17#include <kernel_locks.h>
    1718#include <utils.h>
    1819#include <tty0.h>
    19 #include <iob_driver.h>
    2020#include <ctx_handler.h>
    21 #include <mmc_driver.h>
    22 #include <hba_driver.h>
     21#include <irq_handler.h>
    2322#include <vmem.h>
    2423
    25 #if !defined( NB_IOC_CHANNELS )
    26 # error: You must define NB_IOC_CHANNELS in the hard_config.h file
    27 #endif
    28 
    29 #if ( NB_IOC_CHANNELS > 8 )
    30 # error: NB_IOC_CHANNELS cannot be larger than 8
    31 #endif
    32 
    33 #define in_unckdata __attribute__((section (".unckdata")))
    34 
    35 //////////////////////////////////////////////////////////////////
     24///////////////////////////////////////////////////////////////////////////////////
    3625//               Global variables
    37 //////////////////////////////////////////////////////////////////
    38 
    39 // command list array (one per channel)
    40 hba_cmd_list_t   hba_cmd_list[NB_IOC_CHANNELS] __attribute__((aligned(0x1000)));   
    41 
    42 // command tables array (32 command tables per channel)
    43 hba_cmd_table_t  hba_cmd_table[NB_IOC_CHANNELS][32] __attribute__((aligned(0x1000)));
    44 
    45 // command list physical addresses array (one per channel)
    46 paddr_t          hba_cmd_list_paddr[NB_IOC_CHANNELS];
    47 
    48 // command tables physical addresses array (32 command tables per channel)
    49 paddr_t          hba_cmd_table_paddr[NB_IOC_CHANNELS][32];
    50 
    51 // command list pointer array (one per channel)
    52 unsigned int     hba_cmd_slot[NB_IOC_CHANNELS];
     26///////////////////////////////////////////////////////////////////////////////////
     27
     28// global index ot the task, for each entry in the command list
     29__attribute__((section(".kdata")))
     30unsigned int _hba_gtid[32];
     31
     32// status of the command, for each entry in the command list
     33__attribute__((section(".kdata")))
     34unsigned int _hba_status[32];
     35
     36// command list : up to 32 commands
     37__attribute__((section(".kdata")))
     38hba_cmd_desc_t  _hba_cmd_list[32] __attribute__((aligned(0x1000)));   
     39
     40// command tables array : one command table per entry in command list
     41__attribute__((section(".kdata")))
     42hba_cmd_table_t _hba_cmd_table[32] __attribute__((aligned(0x1000)));
     43
     44// command list write index : next slot to register a command
     45__attribute__((section(".kdata")))
     46unsigned int     _hba_cmd_ptw;
     47
     48// command list read index : next slot to poll a completed command
     49__attribute__((section(".kdata")))
     50unsigned int     _hba_cmd_ptr;
    5351
    5452//////////////////////////////////////////////////////////////////////////////
    55 // This low level function returns the value of register (channel / index)
     53// This low level function returns the value of register (index)
    5654//////////////////////////////////////////////////////////////////////////////
    57 unsigned int _hba_get_register( unsigned int channel,
    58                                 unsigned int index )
    59 {
    60     unsigned int* vaddr = (unsigned int*)SEG_IOC_BASE + channel*HBA_SPAN + index;
     55unsigned int _hba_get_register( unsigned int index )
     56{
     57    unsigned int* vaddr = (unsigned int*)SEG_IOC_BASE + index;
    6158    return _io_extended_read( vaddr );
    6259}
    6360
    6461//////////////////////////////////////////////////////////////////////////////
    65 // This low level function set a new value in register (channel / index) 
     62// This low level function set a new value in register (index) 
    6663//////////////////////////////////////////////////////////////////////////////
    67 void _hba_set_register( unsigned int channel,
    68                         unsigned int index,
     64void _hba_set_register( unsigned int index,
    6965                        unsigned int value )
    7066{
    71     unsigned int* vaddr = (unsigned int*)SEG_IOC_BASE + channel*HBA_SPAN + index;
     67    unsigned int* vaddr = (unsigned int*)SEG_IOC_BASE + index;
    7268    _io_extended_write( vaddr, value );
    7369}
    7470
     71///////////////////////////////////////////////////////////////////////////////
     72//      Extern functions
     73///////////////////////////////////////////////////////////////////////////////
    7574
    7675///////////////////////////////////////////////////////////////////////////////
    7776// This function register a command in both the command list
    7877// and the command table, and updates the HBA_PXCI register.
    79 // It uses the AHCI Scatter/Gather mechanisme to split the user
    80 // buffer in several physical buffers, with the constraint that each physical
    81 // buffer must be an integer number of blocks entirely contained in a single
    82 // page frame.
    8378// return 0 if success, -1 if error
    8479///////////////////////////////////////////////////////////////////////////////
    85 unsigned int _hba_cmd_set( unsigned int  channel,     // channel index
    86                            unsigned int  is_read,     // to memory
    87                            unsigned int  lba,         // logic block address
    88                            paddr_t       buffer,      // buffer physical address
    89                            unsigned int  count )      // number of blocks
    90 {
    91     unsigned int       block_size;     // defined by the block device (bytes)
    92     unsigned int       pxci;           // command list status
    93     unsigned int       cmd_id;         // command index in command list
    94 
     80unsigned int _hba_access( unsigned int       use_irq,
     81                          unsigned int       to_mem,
     82                          unsigned int       lba, 
     83                          unsigned long long buf_paddr,
     84                          unsigned int       count )   
     85{
     86    unsigned int procid  = _get_procid();
     87    unsigned int x       = procid >> (Y_WIDTH + P_WIDTH);
     88    unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH) - 1);
     89    unsigned int p       = procid & ((1<<P_WIDTH)-1);
     90
     91#if GIET_DEBUG_IOC_DRIVER
     92_printf("\n[HBA DEBUG] P[%d,%d,%d] enters _hba_access at cycle %d\n"
     93        "  use_irq = %d / to_mem = %d / lba = %x / paddr = %l / count = %d\n",
     94        x , y , p , _get_proctime() , use_irq , to_mem , lba , buf_paddr, count );
     95#endif
     96
     97    unsigned int       pxci;           // HBA_PXCI register value
     98    unsigned int       ptw;            // command list write pointer
     99    unsigned int       pxis;           // HBA_PXIS register value
    95100    hba_cmd_desc_t*    cmd_desc;       // command descriptor pointer   
    96101    hba_cmd_table_t*   cmd_table;      // command table pointer
    97102
    98     block_size = _hba_get_block_size();
    99 
    100103    // check buffer alignment
    101     if( buffer & (block_size-1) )
    102     {
    103         _puts("\n[GIET ERROR] in _hba_set_cmd() : user buffer not block aligned\n");
     104    if( buf_paddr & 0x1FF )
     105    {
     106        _printf("\n[HBA ERROR] in _hba_access() : buffer not block aligned\n");
    104107        return -1;
    105108    }
    106109
    107     // get command list status from PXCI register
    108     pxci = _hba_get_register( channel, HBA_PXCI );
    109 
    110     // get command index and return error if command list full
    111     cmd_id = hba_cmd_slot[channel];
    112     if( pxci & (1<<cmd_id ) )
    113     {
    114         _puts("\n[GIET ERROR] in _hba_set_cmd() : command list full for channel ");
    115         _putd( channel );
    116         _puts("\n");
    117         return -1;
    118     }
    119 
     110    // get pointer on the next possible entry in command list
     111    ptw = _atomic_increment( &_hba_cmd_ptw , 1 );
     112
     113    // poll PXCI register until pointed entry empty
     114    do
     115    {
     116        // get PXCI register
     117        pxci = _hba_get_register( HBA_PXCI );
     118    }
     119    while ( pxci & (1<<ptw) );
     120   
    120121    // compute pointers on command descriptor and command table   
    121     cmd_desc  = (hba_cmd_desc_t*)(&(hba_cmd_list[channel].desc[cmd_id]));
    122     cmd_table = (hba_cmd_table_t*)(&(hba_cmd_table[channel][cmd_id]));
     122    cmd_desc  = &_hba_cmd_list[ptw];
     123    cmd_table = &_hba_cmd_table[ptw];
    123124
    124125    // set  buffer descriptor in command table
    125     cmd_table->entry[0].dba  = (unsigned int)(buffer);
    126     cmd_table->entry[0].dbau = (unsigned int)(buffer >> 32);
    127     cmd_table->entry[0].dbc  = count * block_size;
     126    cmd_table->entry[0].dba  = (unsigned int)(buf_paddr);
     127    cmd_table->entry[0].dbau = (unsigned int)(buf_paddr >> 32);
     128    cmd_table->entry[0].dbc  = count * 512;
    128129
    129130    // initialize command table header
     
    138139    cmd_desc->prdtl[0] = 1;
    139140    cmd_desc->prdtl[1] = 0;
    140     cmd_desc->ctba     = (unsigned int)(hba_cmd_table_paddr[channel][cmd_id]);
    141     cmd_desc->ctbau    = (unsigned int)(hba_cmd_table_paddr[channel][cmd_id]>>32);
    142     if( is_read ) cmd_desc->flag[0] = 0x00;
    143     else          cmd_desc->flag[0] = 0x40;     
     141    if( to_mem ) cmd_desc->flag[0] = 0x00;
     142    else         cmd_desc->flag[0] = 0x40;     
    144143   
    145     // update PXCI register
    146     _hba_set_register( channel, HBA_PXCI, (1<<cmd_id) );
    147 
    148     // update command pointer
    149     hba_cmd_slot[channel] = (cmd_id + 1)%32;
    150 
    151     return  0;
    152 }
    153 
    154 /* This can be used for a future use with buffer in virtual space
    155 
    156     // get user space page table virtual address
    157     user_pt_vbase     = _get_context_slot(CTX_PTAB_ID);
    158     vpn_min           = buf_vaddr >> 12;
    159     vpn_max           = (buf_vaddr + (block_size*count) - 1) >> 12;
    160     offset            = buf_vaddr & 0xFFF;
    161     offset_last       = (buf_vaddr + (block_size*count) - 1) & 0xFFF;
    162 
    163     // initialize all buffer descriptors in command table
    164     // (loop on all virtual pages covering the user buffer)
    165     for( vpn = vpn_min, buf_id = 0 ; vpn <= vpn_max ; vpn++ )
    166     {
    167         paddr_t      paddr;
    168         unsigned int count;
    169         unsigned int ppn;
    170         unsigned int flags;
    171         unsigned int ko;
    172         unsigned int buf_id = 0;
    173 
    174         // get ppn and flags
    175         _v2p_translate( (page_table_t*)user_pt_vbase,
    176                         vpn,
    177                         &ppn,
    178                         &flags );
    179 
    180         // check access rights
    181         if ((flags & PTE_U) == 0)
     144    // set command in PXCI[ptw]
     145    _hba_set_register( HBA_PXCI, pxci + (1<<ptw) );
     146
     147
     148    /////////////////////////////////////////////////////////////////////
     149    // In synchronous mode, we poll the PXCI register until completion
     150    /////////////////////////////////////////////////////////////////////
     151    if ( use_irq == 0 )
     152    {
     153
     154#if GIET_DEBUG_IOC_DRIVER
     155_printf("\n[HBA DEBUG] _hba_access() : P[%d,%d,%d] launch transfer"
     156        " in polling mode at cycle %d\n",
     157        x , y , p , _get_proctime() );
     158#endif
     159        // disable IRQs in PXIE register
     160        _hba_set_register( HBA_PXIE , 0 );
     161
     162        // poll PXCI[ptw] until command completed by HBA
     163        do
    182164        {
    183             _puts("[GIET ERROR] in _hba_set_cmd() : user buffer not in user space\n");
    184             return -1;
     165            pxci = _hba_get_register( HBA_PXCI ) & (1<<ptw);
     166
     167#if GIET_DEBUG_IOC_DRIVER
     168_printf("\n[HBA DEBUG] _hba_access() : P[%d,%d,%d] wait on HBA_STATUS ...\n",
     169        x , y , p );
     170#endif
    185171        }
    186         if (((flags & PTE_W) == 0 ) && (is_read == 0) )
     172        while( pxci & (1<<ptw) );
     173             
     174        // get PXIS register
     175        pxis = _hba_get_register( HBA_PXIS );
     176
     177        // reset PXIS register
     178        _hba_set_register( HBA_PXIS , 0 );
     179    }
     180
     181    /////////////////////////////////////////////////////////////////
     182    // in descheduling mode, we deschedule the task
     183    // and use an interrupt to reschedule the task.
     184    // We need a critical section, because we must reset the RUN bit
     185        // before to launch the transfer, and we don't want to be
     186    // descheduled between these two operations.
     187    /////////////////////////////////////////////////////////////////
     188    else
     189    {
     190
     191#if GIET_DEBUG_IOC_DRIVER
     192_printf("\n[HBA DEBUG] _hba_access() : P[%d,%d,%d] launch transfer"
     193        " in descheduling mode at cycle %d\n",
     194        x , y , p , _get_proctime() );
     195#endif
     196        unsigned int save_sr;
     197        unsigned int ltid = _get_current_task_id();
     198
     199        // activates HBA interrupts
     200        _hba_set_register( HBA_PXIE , 0x00000001 );
     201
     202        // set _hba_gtid[ptw]
     203        _hba_gtid[ptw] = (procid<<16) + ltid;
     204
     205        // enters critical section
     206        _it_disable( &save_sr );
     207
     208        // reset runnable
     209        _set_task_slot( x, y, p, ltid, CTX_RUN_ID, 0 ); 
     210
     211        // deschedule task
     212        _ctx_switch();                     
     213
     214#if GIET_DEBUG_IOC_DRIVER
     215_printf("\n[HBA DEBUG] _hba_access() : P[%d,%d,%d] resume execution at cycle %d\n",
     216        x , y , p , _get_proctime() );
     217#endif
     218
     219        // restore SR
     220        _it_restore( &save_sr );
     221
     222        // get command status
     223        pxis = _hba_status[ptw];
     224    }   
     225
     226#if GIET_DEBUG_IOC_DRIVER
     227_printf("\n[HBA DEBUG] _hba_access() : P[%d,%d,%d] exit at cycle %d\n",
     228        x , y , p , _get_proctime() );
     229#endif
     230
     231    if ( pxis & 0x40000000 ) return pxis;
     232    else                     return 0;
     233
     234} // end _hba_access()
     235
     236
     237////////////////////////
     238unsigned int _hba_init()
     239{
     240    unsigned int       flags;
     241    unsigned int       vaddr;
     242    unsigned long long paddr;
     243    unsigned int       c;     
     244    unsigned int       pxclb;
     245    unsigned int       pxclbu;
     246
     247    // command list pointers
     248    _hba_cmd_ptw = 0;
     249    _hba_cmd_ptr = 0;
     250
     251    // Command list physical addresse
     252    vaddr  = (unsigned int)(_hba_cmd_list);
     253    paddr  = _v2p_translate( vaddr , &flags );
     254    pxclb  = (unsigned int)paddr;
     255    pxclbu = (unsigned int)(paddr>>32);
     256
     257    // Command tables physical addresses
     258    for( c=0 ; c<32 ; c++ )
     259    {
     260        // compute command table physical address
     261        // for one entry in the command list
     262        vaddr = (unsigned int)(&_hba_cmd_table[c]);
     263        paddr = _v2p_translate( vaddr , &flags );
     264
     265        // initialise the corresponding command descriptor
     266        _hba_cmd_list[c].ctba  = (unsigned int)paddr;
     267        _hba_cmd_list[c].ctbau = (unsigned int)(paddr>>32);
     268    }
     269
     270    // set HBA registers
     271    _hba_set_register( HBA_PXCLB , pxclb  );
     272    _hba_set_register( HBA_PXCLBU, pxclbu );
     273    _hba_set_register( HBA_PXIE  , 0      );
     274    _hba_set_register( HBA_PXIS  , 0      );
     275    _hba_set_register( HBA_PXCI  , 0      );
     276    _hba_set_register( HBA_PXCMD , 1      );
     277
     278    return 0;
     279}
     280
     281
     282/////////////////////////////////////
     283void _hba_isr( unsigned int irq_type,   // HWI / WTI
     284               unsigned int irq_id,     // index returned by ICU
     285               unsigned int channel )   // unused
     286{
     287    // get HBA_PXCI containing commands status
     288    unsigned int pxci = _hba_get_register( HBA_PXCI );
     289
     290    // scan active commands from (_hba_cmd_ptr) to (_hba_cmd_ptw-1)
     291    unsigned int c;
     292    for ( c = _hba_cmd_ptr ;
     293          c != _hba_cmd_ptw ;
     294          c = (c + 1) % 32 )
     295    {
     296        if ( (pxci & (1<<c)) == 0 )    // command completed
    187297        {
    188             _puts("[GIET ERROR] in _hba_set_cmd() : user buffer not writable\n");
    189             return -1;
     298            // increment read pointer;
     299            _hba_cmd_ptr++;
     300
     301            // save PXIS register
     302            _hba_status[c] = _hba_get_register( HBA_PXIS );
     303
     304            // reset PXIS register
     305            _hba_set_register( HBA_PXIS , 0 );
     306 
     307            // identify waiting task
     308            unsigned int remote_procid  = _hba_gtid[c]>>16;
     309            unsigned int ltid           = _hba_gtid[c] & 0xFFFF;
     310            unsigned int remote_cluster = remote_procid >> P_WIDTH;
     311            unsigned int remote_x       = remote_cluster >> Y_WIDTH;
     312            unsigned int remote_y       = remote_cluster & ((1<<Y_WIDTH)-1);
     313            unsigned int remote_p       = remote_procid & ((1<<P_WIDTH)-1);
     314 
     315            // re-activates waiting task
     316            _set_task_slot( remote_x,
     317                            remote_y,
     318                            remote_p,
     319                            ltid,
     320                            CTX_RUN_ID,
     321                            1 );
     322
     323            // send a WAKUP WTI to processor running the waiting task
     324            _xcu_send_wti( remote_cluster ,
     325                           remote_p ,
     326                           0 );          // don't force context switch
     327
     328#if GIET_DEBUG_IOC_DRIVER 
     329unsigned int procid  = _get_procid();
     330unsigned int x       = procid >> (Y_WIDTH + P_WIDTH);
     331unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
     332unsigned int p       = procid & ((1<<P_WIDTH)-1);
     333_printf("\n[HBA DEBUG] Processor[%d,%d,%d] executes _hba_isr() :\n"
     334        "  resume task %d running on P[%d,%d,%d] / status = %x at cyle %d\n",
     335        x , y , p ,
     336        ltid , remote_x , remote_y , remote_p , _hba_status[c] , _get_proctime() );
     337#endif
    190338        }
    191 
    192         // check buffer index overflow
    193         if( buf_id > 245 )
     339        else                         // command non completed
    194340        {
    195             _puts("[GIET ERROR] in _hba_set_cmd() : max number of buffers is 248\n");
    196             return -1;   
    197         }
    198 
    199         // buffer allocation
    200         if( vpn == vpn_min )       // first page: one single buffer
    201         {
    202             paddr = (((paddr_t)ppn) << 12) + offset;
    203             count = 0x1000 - offset;
    204             cmd_table->entry[buf_id].dba  = (unsigned int)(paddr);
    205             cmd_table->entry[buf_id].dbau = (unsigned int)(paddr >> 32);
    206             cmd_table->entry[buf_id].dbc  = count;
    207 
    208             buf_id++;
    209         }
    210         else if( vpn == vpn_max )  // last page: one single buffer
    211         {
    212             paddr = (((paddr_t)ppn) << 12);
    213             count = offset_last;
    214             cmd_table->entry[buf_id].dba  = (unsigned int)(paddr);
    215             cmd_table->entry[buf_id].dbau = (unsigned int)(paddr >> 32);
    216             cmd_table->entry[buf_id].dbc  = count;
    217 
    218             buf_id++;
    219         }
    220         else if( offset )          // midle page and offset != 0: two buffers 
    221         {
    222             paddr = (((paddr_t)ppn) << 12);
    223            
    224             count = offset;
    225             cmd_table->entry[buf_id].dba  = (unsigned int)(paddr);
    226             cmd_table->entry[buf_id].dbau = (unsigned int)(paddr >> 32);
    227             cmd_table->entry[buf_id].dbc  = count;
    228 
    229             buf_id++;
    230 
    231             paddr = (((paddr_t)ppn) << 12) + offset;
    232             count = 0x1000 - offset;
    233             cmd_table->entry[buf_id].dba  = (unsigned int)(paddr);
    234             cmd_table->entry[buf_id].dbau = (unsigned int)(paddr >> 32);
    235             cmd_table->entry[buf_id].dbc  = count;
    236 
    237             buf_id++;
    238         }
    239         else                      // middle page and offset == 0: one buffer
    240         {
    241             paddr = (((paddr_t)ppn) << 12);
    242             count = 0x1000;
    243             cmd_table->entry[buf_id].dba  = (unsigned int)(paddr);
    244             cmd_table->entry[buf_id].dbau = (unsigned int)(paddr >> 32);
    245             cmd_table->entry[buf_id].dbc  = count;
    246 
    247             buf_id++;
     341            break;
    248342        }
    249343    }
    250 */
    251 
    252 
    253 //////////////////////////////////////////////
    254 unsigned int _hba_init( unsigned int channel )
    255 {
    256     unsigned int ppn;
    257     unsigned int flags;
    258     unsigned int vbase;
    259     unsigned int c;               // c == command index
    260 
    261     // get page_table pointer
    262     unsigned int pt = _get_context_slot(CTX_PTAB_ID);
    263 
    264     // HBA registers TODO: ne faut_il pas un V2P pour PXCLB/PXCLBU ? (AG)
    265     _hba_set_register( channel, HBA_PXCLB , (unsigned int)&hba_cmd_list[channel] );
    266     _hba_set_register( channel, HBA_PXCLBU, 0 );
    267     _hba_set_register( channel, HBA_PXIE  , 0x40000001 );
    268     _hba_set_register( channel, HBA_PXIS  , 0 );
    269     _hba_set_register( channel, HBA_PXCI  , 0 );
    270     _hba_set_register( channel, HBA_PXCMD , 1 );
    271 
    272     // command list pointer       
    273     hba_cmd_slot[channel] = 0;
    274 
    275     // Command list physical addresse
    276     vbase = (unsigned int)(&hba_cmd_list[channel]);
    277     _v2p_translate( (page_table_t*)pt,
    278                      vbase>>12,
    279                      &ppn,
    280                      &flags );
    281     hba_cmd_list_paddr[channel] = ((paddr_t)ppn) | (vbase & 0xFFF);
    282 
    283     // Command tables physical addresses
    284     for( c=0 ; c<32 ; c++ )
    285     {
    286         vbase = (unsigned int)(&hba_cmd_table[channel][c]);
    287         _v2p_translate( (page_table_t*)pt,
    288                          vbase>>12,
    289                          &ppn,
    290                          &flags );
    291         hba_cmd_table_paddr[channel][c] = ((paddr_t)ppn) | (vbase & 0xFFF);
    292     }
    293 
    294     return 0;
    295 }
    296 
    297 ///////////////////////////////////////////////
    298 unsigned int _hba_write( unsigned int  channel,
    299                          unsigned int  mode,
    300                          unsigned int  lba,
    301                          paddr_t       buffer,
    302                          unsigned int  count )
    303 {
    304     return _hba_cmd_set( channel,
    305                          0,         // write
    306                          lba,
    307                          buffer,
    308                          count );
    309 }
    310 
    311 //////////////////////////////////////////////
    312 unsigned int _hba_read( unsigned int  channel,
    313                         unsigned int  mode,
    314                         unsigned int  lba,
    315                         paddr_t       buffer,
    316                         unsigned int  count )
    317 {
    318     return _hba_cmd_set( channel,
    319                          1,          // read
    320                          lba,
    321                          buffer,
    322                          count );
    323 }
    324 
    325 //////////////////////////////////
    326 unsigned int _hba_get_block_size()
    327 {
    328     // TODO The block size must be obtained from the hardware...
    329     return 512;
    330 }
    331 
    332 ////////////////////////////////////////////////////
    333 unsigned int _hba_get_status( unsigned int channel )
    334 {
    335 
    336     if( channel >= NB_IOC_CHANNELS )
    337     {
    338         _puts("\n[GIET ERROR] in _hba_get_status() : illegal channel\n");
    339         _exit();
    340     }
    341 
    342     // get HBA_PXIS value
    343     unsigned int status = _hba_get_register( channel, HBA_PXIS );
    344 
    345     // reset HBA_PXIS
    346     _hba_set_register( channel, HBA_PXIS, 0 );
    347 
    348     return status;
    349 }
     344} // end _hba_isr()
    350345
    351346// Local Variables:
Note: See TracChangeset for help on using the changeset viewer.