fileio example on HD more than 2GB

Grigori Khmyrov grigori_khmyrov at uml.edu
Mon May 1 16:57:41 UTC 2006


It just fixes problem for me. I'm not sure it's a right way to do it.
Some IDE expert should look at this. I'm not.

The changes are very simple

1. rtems-4.6.2\c\src\libchip\ide\ata.c
line 30 was:
#define DEBUG
line 30 now is:
//#define DEBUG

2. rtems-4.6.2\c\src\lib\libbsp\i386\pc386\ide\ide.c
line 182 was:
  while ((status_val & IDE_REGISTER_STATUS_DRQ) &&
line 182 now is:
  while (/*(status_val & IDE_REGISTER_STATUS_DRQ) && */

I don't know why but it looks like for some IDE controllers 
IDE_REGISTER_STATUS_DRQ is wrong.
And program exits while loop and never reads rest of the block.

Grigori


Joel Sherrill wrote:

> Grigori Khmyrov wrote:
>
>> I dig deeper in fileio example and found fixes for problems I had.
>>
>
> Can you produce a patch or send myself and Thomas Doerfler (cc'ed)
> your files for merger?  I can't tell with 100% certainty the precise 
> edits
> you made.
>
> The first problem looks like there might need to be a semaphore release
> at the return.  I don't understand the second problem.
>
>>
>> I'm reminding. I had 4 computers: 3 laptops and 1 old desktop (with 4 
>> different small <2GB HDs)
>>
>> Only one laptop worked OK with fileio example.
>>
>> 1. Two other laptops: program stopped at line 1231 of 
>> cpukit/libblock/src/bdbuf.c
>> _CORE_mutex_Seize(&bd_buf->transfer_sema, 0, TRUE, 
>> WATCHDOG_NO_TIMEOUT, level);
>>
>> Fix is: I commented out #define DEBUG in ata.c
>> It was defined!!!
>>
>> As a result the code was executed
>> #ifdef DEBUG
>>        /*
>>         * read IDE_REGISTER_ALTERNATE_STATUS instead IDE_REGISTER_STATUS
>>         * to prevent clearing of pending interrupt
>>         */
>>        ide_controller_read_register(ctrl_minor,
>>                                     IDE_REGISTER_ALTERNATE_STATUS,
>>                                     &val);
>>        if (val & IDE_REGISTER_STATUS_BSY)
>>            return;
>> #endif
>> val was not busy only for one laptop. For others it never released
>> semaphore and returned without any messages!
>>
>> 2. On the desktop error code after init partition was 25 - INTERNAL 
>> RTEMS ERROR
>>
>> I found ide read block function never read all 512 bytes only 508 of 
>> them.
>> As a result it was no MSDOS signature in MBR (sector 0).
>>
>> In ide.c I commented out status_val usage:
>>
>> /*=========================================================================*\ 
>>
>> | 
>> Function:                                                                 
>> |
>> \*-------------------------------------------------------------------------*/ 
>>
>> void pc386_ide_read_block
>> (
>> /*-------------------------------------------------------------------------*\ 
>>
>> | 
>> Purpose:                                                                  
>> |
>> |  read a IDE controller data 
>> block                                         |
>> +---------------------------------------------------------------------------+ 
>>
>> | Input 
>> Parameters:                                                         |
>> \*-------------------------------------------------------------------------*/ 
>>
>> int minor,
>> unsigned16 block_size,
>> blkdev_sg_buffer *bufs,
>> rtems_unsigned32 *cbuf,
>> rtems_unsigned32 *pos
>> )
>> /*-------------------------------------------------------------------------*\ 
>>
>> | Return 
>> Value:                                                             |
>> |    
>> <none>                                                                 |
>> \*=========================================================================*/ 
>>
>> {
>>  unsigned32  port = IDE_Controller_Table[minor].port1;
>>  unsigned16  cnt = 0;
>>  unsigned32  llength = bufs[(*cbuf)].length;
>> //  unsigned8 status_val;
>>  unsigned16 *lbuf = (unsigned16 *)
>>    ((unsigned8 *)(bufs[(*cbuf)].buffer) + (*pos));
>> //#define DEBUG_OUT
>>
>> //  inport_byte(port+IDE_REGISTER_STATUS,status_val);
>>  while (/*(status_val & IDE_REGISTER_STATUS_DRQ) && */
>>         (cnt < block_size)) {
>>    inport_word(port+IDE_REGISTER_DATA,*lbuf);
>>
>> #ifdef DEBUG_OUT
>>    printk("%d:0x%x:%d ",cnt, *lbuf, status_val);
>> #endif
>>    lbuf++;
>>    cnt    += sizeof(*lbuf);
>>    (*pos) += sizeof(*lbuf);
>>    if ((*pos) == llength) {
>>      (*pos) = 0;
>>      (*cbuf)++;
>>      lbuf = bufs[(*cbuf)].buffer;
>>      llength = bufs[(*cbuf)].length;
>>    }
>> //    inport_byte(port+IDE_REGISTER_STATUS,status_val);
>>  }
>> #ifdef DEBUG_OUT
>>  printk("\npc386_ide_read_block() pos = %d\n", (*pos));
>> printk("read ide, llength = %d, block_size = %d, 
>> IDE_REGISTER_STATUS_DRQ %d\n",
>>  llength, block_size, IDE_REGISTER_STATUS_DRQ);
>> #endif
>> }
>>
>> It works now with all ide/HD I have.
>> I use RTEMS 4.6.2.
>> I change only my local versions of files.
>>
>> Can somebody look at the current version. I don't work with RTEMS cvs 
>> for now.
>>
>> Thank you,
>> Grigori
>>
>>
>> Grigori Khmyrov wrote:
>>
>>> Can RTEMS handle big hard drives?
>>> Any help appreciated in solving this mystery.
>>>
>>> After that big discussion about FileIO example we got it working.
>>> But it still some issues.
>>>
>>> 500 MB Hard drive    500 MB FAT16 partition   ---    works OK
>>>    3 GB Hard drive     800 MB FAT16 partition   ---   DOESN'T work
>>>    4 GB Hard drive         2 GB  FAT16 partition   ---   DOESN'T work
>>>
>>> It's same like Yan Lou reported:
>>> Problem is in initializing partition of /dev/hda using FileIO  example.
>>> Program stops at 1231 of cpukit/libblock/src/bdbuf.c
>>>
>>> _CORE_mutex_Seize(&bd_buf->transfer_sema, 0, TRUE,
>>>                              WATCHDOG_NO_TIMEOUT, level);
>>>
>>> Here is the call graph:
>>>
>>> in cpukit/libblock/src/ide_part_table.c
>>>
>>> rtems_ide_part_table_initialize() --> rtems_ide_part_table_get() 
>>> -->  read_mbr() --> get_sector() --> rtems_bdbuf_read()
>>>
>>> in cpukit/libblock/src/bdbuf.c
>>>
>>> rtems_bdbuf_read() --> _CORE_mutex_Seize()
>>>
>>> Thank you,
>>> Grigori
>>>
>>
>




More information about the users mailing list