⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ide_drv.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 5 页
字号:

            /* It is atapi */
            pc->drive[pdr->logical_unit_number].protocol = 2;
            // PVO 11-26-99 just send reset. don't treat as a command
             ide_wr_command(pc, IDE_CMD_SOFT_RESET);
			 /* reset the drive */
//          ide_command(IDE_CMD_SOFT_RESET, pc, pdr->logical_unit_number, 0, 0);            
            for(i=0;i<6;i++)
            {
                if(atapi_command(ATAPI_PKT_CMD_TEST_UNIT_READY, pc, pdr->logical_unit_number))
                    break;
                ks_sleep((word)(2*ks_ticks_p_sec()));
            }
                
            pc->user_address = (PFBYTE) &buf[0];
            if(tc_comparen(((PFBYTE)buf)+54, (PFBYTE)"SL1-02", 6))                          /* If a HIMAWARI drive? Jerry*/
            {
                // ??? Do first time to make sure MC is clear (needed by some LS-120 drives)
                ide_command(IDE_CMD_GET_MEDIA_STATUS, pc, pdr->logical_unit_number, 0, 0);
                if (ide_command(IDE_CMD_GET_MEDIA_STATUS, pc, pdr->logical_unit_number, 0, 0))
                {
                    if (ide_command(ATAPI_CMD_IDENT, pc, pdr->logical_unit_number, 0, 0))
                    {
                        /* capture the media descriptor for the format routine */
                        switch(pc->drive[pdr->logical_unit_number].medium_type_code=(byte)buf[4])                                                   /*                         Bytes/  Sectors/                */
                        {             /*                    Cyl H  Sector   Track   Capacity    */
                            case    0x30: /* Formatted   UHD    963 8    512      32    120Mb */
                            case    0x31: /* Unformatted UHD    963 8    512      32    120Mb */
                            case    0x20: /* Unformatted HD      80 2    512      18    1.44Mb*/
                            case    0x24:   /* Formatted HD      80 2    512      18    1.44Mb*/
                            case    0x26:   /* DMF               80 2    512      21    1.7Mb*/
                                pc->drive[pdr->logical_unit_number].media_descriptor=0xf0;
                                pc->drive[pdr->logical_unit_number].allocation_unit=0x01;
                                break;
                            case    0x22:   /* Formatted NEC     77 2   1024       8    1.20Mb*/
                            case    0x23:   /* Formatted Toshiba 80 2    512      15    1.20Mb*/
                                pc->drive[pdr->logical_unit_number].media_descriptor=0xf9;          
                                pc->drive[pdr->logical_unit_number].allocation_unit=0x01;
                                break;
                            case    0x27:   /* NEC-DMF           77 2    512       9    720Kb*/
                            case    0x10:   /* Unformatted DD    80 2    512       9    720Kb*/
                            case    0x11:   /* Formatted DD      80 2    512       9    720Kb*/
                                pc->drive[pdr->logical_unit_number].media_descriptor=0xf9;          
                                pc->drive[pdr->logical_unit_number].allocation_unit=0x02;
                                break;
                            default:
                                return(FALSE);
                        }
                    }
                }
                else
                    return(FALSE);
            }                                                                       // its not a Himawari drive is it a CDROM?
            else
            {
/* CDROM JERRY  START */
                if((to_WORD((byte *) &buf[0])&0xdf03)==0x8500)                                      
                {                                                           
                    pc->drive[pdr->logical_unit_number].media_descriptor=0xef;                
                    pc->drive[pdr->logical_unit_number].CMD_DRQ_type=(byte)(to_WORD((byte *) &buf[0])&0x60);
                }                                                           
                else                                                           
                    return(FALSE);                                                 
/* CDROM JERRY  STOP */
            }
        }
        else
#endif /* (IDE_USE_ATAPI) */
            return(FALSE);
    }
    else
    {
        // BUG BUG - In CDFS system we should d diagnostics here. 
        pc->drive[pdr->logical_unit_number].media_descriptor=0xf8; /* assume hard disk media */
    }
    pc->drive[pdr->logical_unit_number].num_cylinders = to_WORD((byte *) &buf[1]);
    heads   = (byte) (to_WORD((byte *) &buf[3]));
    sectors  = (byte)(to_WORD((byte *) &buf[6]));
    pc->drive[pdr->logical_unit_number].max_multiple = (byte) (to_WORD((byte *) &buf[47]) & 0xff);
    
    
    if (to_WORD((byte *) &buf[49]) & 0x200)
    {
        pc->drive[pdr->logical_unit_number].supports_lba = TRUE;
        /* Get highword low word of highest lba */
        ltemp = to_WORD((byte *) &buf[61]);
        ltemp <<= 16;
        ltemp += to_WORD((byte *) &buf[60]);

		ltemp2 = (dword) pc->drive[pdr->logical_unit_number].num_cylinders;
		ltemp2 = (dword) (ltemp2 * heads);
		ltemp2 = (dword) (ltemp2 * sectors);

		tm_printf("lba fields 60:61 yield %ld h*c*n yield %ld\n", (dword)ltemp, (dword) ltemp2);

	    pc->drive[pdr->logical_unit_number].total_lba = ltemp;
    }
    else
    {
        pc->drive[pdr->logical_unit_number].supports_lba = FALSE;
        pc->drive[pdr->logical_unit_number].total_lba = 0;
    }
    
    /* Our local view of the drive for block to track::sector::head xlations */
    pc->drive[pdr->logical_unit_number].num_heads   =   heads;
    pc->drive[pdr->logical_unit_number].sec_p_track = sectors;
    pc->drive[pdr->logical_unit_number].sec_p_cyl   =  (word) heads;
    pc->drive[pdr->logical_unit_number].sec_p_cyl   =  (word) (pc->drive[pdr->logical_unit_number].sec_p_cyl  * sectors);

#if (IDE_USE_ATAPI)
    /* If it's an ATAPI IDE drive enable media status notification */
    if (pc->drive[pdr->logical_unit_number].protocol == 2)
        ide_set_features(pc, pdr->logical_unit_number, 0x95, 0);
#endif

#if (USE_SETPARMS)
#if (IDE_USE_ATAPI)
   /* Initialize drive parms (on hard drives only, not ATAPI drives) */
   if (pc->drive[pdr->logical_unit_number].protocol != 2)  /* if not ATAPI drive: */
#endif
      if (!ide_command_setparms(pc, pdr->logical_unit_number, heads, sectors))  
      {
         return(FALSE);
      }
#endif
	
	/* 11-10-2000 - New code. Only do SETM on open. We had been doing it
	   on every read & write which caused a cache flush and slowed down io 
	   Thanks to Paul Swan. */
	if (pc->drive[pdr->logical_unit_number].max_multiple > 1)
	{
	    if (!ide_command(IDE_CMD_SETM, pc, pdr->logical_unit_number, 0, 0))
		{
	        return(FALSE);
		}
	}


    pc->drive[pdr->logical_unit_number].open_count++;                           /*CDROM Support Jerry */
    return(TRUE);
}

/* Read/write function: */

BOOLEAN ide_io(int driveno, dword sector, void *buffer, word count, BOOLEAN reading)    /*__fn__*/
{
BOOLEAN ret_val;
PIDE_CONTROLLER pc;
DDRIVE *pdr;


    pdr = pc_drno_to_drive_struct(driveno);
    if (!pdr)
        return(FALSE);

    pc = &controller_s[pdr->controller_number];

    if (!count || !pc)                      /* Must have a count */
        return(FALSE);

    ret_val = FALSE;

    /* Set up a counter for data transfer (See ide_isr) */
    pc->sectors_remaining = count;
//  if (op == ERASING)
//  {
//      ret_val = ide_command(IDE_CMD_ERASES, pc, pdr->logical_unit_number, sector, count);
//  }
    if (reading)
    {
        pc->user_address = (PFBYTE) buffer;
        /* Use read multiple command */
        if ((count > 1) && (pc->drive[pdr->logical_unit_number].max_multiple > 1))
        {
            /* Call set multiple */
            ret_val = ide_command_read_multiple(pc, pdr->logical_unit_number, sector, count);
            if (!ret_val)
            {
                /* Set up a counter for data transfer (See ide_isr) */
                pc->sectors_remaining = count;
                goto non_multiple_read;
            }
        }
        else
        {
non_multiple_read:
            do 
            {
                pc->block_size = 1;
                ret_val = ide_command(IDE_CMD_READS, pc, pdr->logical_unit_number, sector, count);
                if (!ret_val)
                {
                        break;  /* Break out of do loop */  
                }
            } while(!ret_val);
        }
    }
    else // WRITING
    {
        pc->user_address = (PFBYTE) buffer;
        if ( (count > 1) && (pc->drive[pdr->logical_unit_number].max_multiple > 1))
        {
            /* Try write multiple. */
            ret_val = ide_command_write_multiple(pc, pdr->logical_unit_number, sector, count);
            if (!ret_val)
            {
                pc->sectors_remaining = count;
                goto non_multiple_write;
            }
        }
        else
        {
non_multiple_write:
            pc->block_size = 1;
            ret_val =   ide_command(IDE_CMD_WRITES, pc, pdr->logical_unit_number, sector, count);
        }
    }
    return(ret_val);
}


static BOOLEAN ide_command(byte command, PIDE_CONTROLLER pc, int logical_unit_number, dword blockno, word nblocks)
{
    ide_clear_voregs(pc);               /* Clear virtual output registers */
     /* Call ide_rdwr_setup to set transfer addresses, sector_count, sector_number,
        cylinder_low, cylinder_hi and drive_head */
    if ((command == IDE_CMD_ERASES) ||
        (command == IDE_CMD_READS) ||
        (command == IDE_CMD_READM) ||
        (command == IDE_CMD_WRITEM_NE) ||
        (command == IDE_CMD_WRITEM) ||
        (command == IDE_CMD_WRITES_NE) ||
        (command == IDE_CMD_WRITES) )
    {
        if (!ide_rdwr_setup(pc, logical_unit_number, blockno, nblocks))
            return(FALSE);
        pc->timer = (word)TIMEOUT_RDWR;
    }
    else
    {
        pc->timer = (word)TIMEOUT_TYPICAL;
    }
    pc->vo_drive_head  |= 0x20;                 /* Bit five is always one */
    if (logical_unit_number)                                /* Bit four is drive (1 or 0) */
        pc->vo_drive_head |= 0x10;              /* select device 1 (slave) */
    if (command == IDE_CMD_ERASES)              /* Erase sets bit 7 */
        pc->vo_drive_head |= 0x80;
    if (command == IDE_CMD_SETM)
    {
        pc->block_size = pc->drive[logical_unit_number].max_multiple;
        pc->vo_sector_count = pc->block_size;
    }
	/* 11-10-2000 - New code. Since we don't call SETM on each WRITEM or 
	   READM we must set block size now on the READM, WRITEM calls */
    if ((command == IDE_CMD_READM)||
    	(command == IDE_CMD_WRITEM))
    {
        pc->block_size = pc->drive[logical_unit_number].max_multiple;
    }

	pc->vo_command = command;

    /* Call the processing routine */
    return(ide_do_command(pc));
}
 
#if (IDE_USE_ATAPI)

BOOLEAN atapi_command(byte command, PIDE_CONTROLLER pc, int logical_unit_number)
{
    ide_clear_voregs(pc);               /* Clear virtual output registers */
     /* Call ide_rdwr_setup to set transfer addresses, sector_count, sector_number,
        cylinder_low, cylinder_hi and drive_head */
    if(command==ATAPI_PKT_CMD_FORMAT_UNIT)
        pc->timer=(word)TIMEOUT_FORMAT;
    else
        pc->timer = (word)TIMEOUT_TYPICAL;
    pc->vo_drive_head  |= 0x20;                 /* Bit five is always one */
    if (logical_unit_number)                                /* Bit four is drive (1 or 0) */
        pc->vo_drive_head |= 0x10;              /* select device 1 (slave) */
    pc->vo_command = command;
    
    /* Call the processing routine */
    return(ide_do_command(pc));
}
#endif  /*  #if (IDE_USE_ATAPI) */

/* ........................................................................
    .... End Device driver external interface routines.             .......
    .......................................................................*/
#if (IDE_USE_SET_FEATURES || IDE_USE_ATAPI)
static BOOLEAN ide_set_features(PIDE_CONTROLLER pc, int logical_unit_number, byte feature, byte config) /* __fn__ */
{
    ide_clear_voregs(pc);               /* Clear virtual output registers */
    if (logical_unit_number)                            /* Bit four is drive (1 or 0) */
        pc->vo_drive_head |= 0x10;          /* select device 1 (slave) */
    pc->vo_feature      = feature;
    pc->vo_sector_count = config;
    pc->vo_command = IDE_CMD_SETF;
    pc->timer = (word)TIMEOUT_TYPICAL;
 /* Call the processing routine */
    return(ide_do_command(pc));
}
#endif

//DM: commented out conditional to re-enable. Put back conditional if
//    routine really is no good for CDROM
//#ifndef CDFS_ONLY

/* Command execution routines. */

/*  ide_command_diags - Execute drive diagnostics
*
*
*
* Returns:
*   TRUE if the drive diagnostic succeeded else FALSE.
*   
*   This routine execute a diagnostic request. If the diagnostic succeeds
*   it returns TRUE otherwise it returns FALSE.
*
* called by: ide_drive_init
*
* This routine is portable
*   
*/

static BOOLEAN ide_command_diags(PIDE_CONTROLLER pc) /* __fn__ */
{
    ide_clear_voregs(pc);               /* Clear virtual output registers */
    pc->vo_command = IDE_CMD_DIAG;      /* Command */
    pc->timer = (word)TIMEOUT_DIAG;
    return(ide_do_command(pc));
}
//DM: commented out conditional to re-enable
//#endif // CDFS_ONLY



/*  ide_command_setparms - Set drive parameters

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -