fileio example on HD more than 2GB
Thomas Doerfler (nt)
Thomas.Doerfler at imd-systems.de
Mon May 1 17:05:35 UTC 2006
Grigori, Joel,
I will have a look at the issues tomorrow.
wkr,
thomas.
Grigori Khmyrov schrieb:
> 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
>>>>
>>>
>>
--
--------------------------------------------
IMD Ingenieurbuero fuer Microcomputertechnik
Thomas Doerfler Herbststrasse 8
D-82178 Puchheim Germany
email: Thomas.Doerfler at imd-systems.de
PGP public key available at:
http://www.imd-systems.de/pgpkey_en.html
More information about the users
mailing list