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