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

📄 fl_drver.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 5 页
字号:
            WriteRealMem(dma_buffer, parms_buffer, 512);
            if (!fl_dma_init((DMAPTYPE) dma_buffer,(word)((fl_devparms[parmindex].sectors_per_track)<<2), FALSE))
           #endif
                {
                     pc_free_buf(buf,TRUE);
                return(fl_report_error(FLERR_DMA, FALSE));
                }

            /* Clear any outstanding interrupt complete messages */
            OS_FLOPPY_SIGNAL_BIND(0);
            OS_FLOPPY_SIGNAL_CLEAR(0);

            fl_motor_on(driveno);

            if (!fl_command_phase(&b))
            {
                goto fmterr;
            }
            /* Wait for the io to complete */
            if (!fl_waitdma((int)FLTMO_FMTTRACK))
                goto fmterr;
#else
            shadow_dig_out &= ~DORB_DMAEN;
            fl_write_dor(shadow_dig_out);

            fl_motor_on(driveno);

            for (i = 0; i < 10; i++)
                if ((ready = fl_ready())== FL_TOHOST)
                    fl_read_data();
                else
                    break;
            for (i = 0; i < b.n_to_send; i++)
            {
                if ((ready = fl_ready()) != FL_FRHOST)
                {
                    shadow_dig_out |= DORB_DMAEN;
                    fl_write_dor(shadow_dig_out);
                          pc_free_buf(buf,TRUE);
                    return(fl_report_error(FLERR_CHIP_HUNG, FALSE));
                }

                /* Write command bytes. On the last byte call the read routine
                   so it can set up the last command byte and be ready to
                   read the data without overruns */
                if (i < (b.n_to_send-1))
                    fl_write_data(b.commands[i]);
                else
                    residual = polled_write(
                               (byte KS_FAR *) parms_buffer,
                               (word)((fl_devparms[parmindex].sectors_per_track)<<2)
                                , b.commands[i]);
                    if (residual)
                    {
#if (!defined(ERTFS_SA))
                       DEBUG_ERROR("Format failed resid", NOVAR, 0, 0);
#else
                        tm_printf("Format failed resid\n");
#endif
                       goto fmterr;
                    }
            }

            /* Out of dma mode */
            shadow_dig_out |= DORB_DMAEN;
            fl_write_dor(shadow_dig_out);
#endif

            if (!fl_results_phase(&b))
                goto fmterr;

            /* Check status register 0 for abnormal termination */
            if (b.results[0] & (BIT7|BIT6))
                goto fmterr;


        }
    }
     pc_free_buf(buf,TRUE);
    return(TRUE);

fmterr:
     pc_free_buf(buf,TRUE);
    return(fl_report_error(FLERR_FORMAT, FALSE));
}



/*  fl_controller_init - Initialize the floppy controller
* 
* summary
* BOOLEAN fl_controller_init()
*
*
* Inputs:
*
* Returns:
*   TRUE on success else FALSE.
*   
* This routine zeroes out our data structures (floppy[0,1]). Then calls
* the host specific initialization code fl_establish() (sets up vectors/
* watchdogs). Then it attempts to reset the controller. If all is succesful
* it returns TRUE. 
*
* Called by floppy_open()
*
*/

static BOOLEAN fl_controller_init()                                    /* __fn__ */
{
    selected_floppy = 0;
    pc_memfill(&floppy[0], sizeof(_FLOPPY), 0);
#if (N_FLOPPY_UNITS == 2)
    pc_memfill(&floppy[1], sizeof(_FLOPPY), 0);
#endif
    /* Initialize interrupt vectors, timer, motor timer etc */
#if (defined(ERTFS_SA))
    hook_floppy_interrupt(6);
#else
    ks_hook_interrupt(6, (PFVOID) 0, floppy_isr, (RTIPINTFN_POINTER) 0, 0);
#endif
    /* Clear any pending signals */
    OS_FLOPPY_SIGNAL_CLEAR(0);

    floppy[0].drive_type = os_floppy_type(0);
    floppy[0].media_type = (byte) DT_NONE;
#if (N_FLOPPY_UNITS == 2)
    floppy[1].drive_type = os_floppy_type(1);
    floppy[1].media_type = (byte) DT_NONE;
#endif
    return(fl_reset_controller());
}

/* Issue a reset through the digital output register and wait for 
   an interrupt. */
static BOOLEAN    fl_reset_controller()                                  /*__fn__*/
{
COMMAND_BLOCK b;

    /* Clear any outstanding interrupt complete messages */
    OS_FLOPPY_SIGNAL_BIND(0);
    OS_FLOPPY_SIGNAL_CLEAR(0);
    
     /* reset the floppy by toggling the reset line (BIT 3) */
    shadow_dig_out = 0;

    fl_write_dor(shadow_dig_out);
    /* Clear reset. Enable DMA and interrupts */
    shadow_dig_out |= (DORB_SRSTBAR|DORB_DMAEN);
    fl_write_dor(shadow_dig_out);

    /* Wait up to 5 seconds for the interrupt to occur.*/
    if (!fl_waitint((int)FLTMO_RESET))
    {
        return(fl_report_error(FLERR_RESET, FALSE));
    }
    /* Delay a little otherwise sense interrupt fails */
    ks_sleep((word)(FL_SPINUP));
    if (!fl_sense_interrupt(&b))
        return(fl_report_error(FLERR_RESET, FALSE));

    return(TRUE);
}

/* fl_claim - Claim the controller for IO to a drive
* 
* Summary:
*
* BOOLEAN fl_claim(driveno)
*
*
* Inputs:
*   int  driveno      - 0 or 1 = a: b:
*
* Returns:
*   TRUE on success else FALSE.
*   
*   This routine is called by floppy_io each time it will do io to a drive.
*   if the drive is the current active drive it writes the data rate reg and 
*   returns. Otherwise the other drive will be accessed. If the medai type
*   has not been established this is done. The controller timing parameters
*   are specified and the data rate is set.
*       
*/

static BOOLEAN fl_claim(int driveno)                                  /*__fn__*/
{
    if (selected_floppy != (driveno+1))
    {
        selected_floppy = (int ) (driveno+1);
        if (floppy[driveno].media_type == DT_NONE)
        {
            if (!fl_establish_media(driveno))
                return(FALSE);
        }
        else if (!fl_specify(driveno))
            return(fl_report_error(FLERR_SPECIFY, FALSE));
        selected_floppy = (int ) (driveno+1);
    }
    fl_write_drr(floppy[driveno].data_rate);
    return(TRUE);
}

/* fl_establish_media - Vary the data rate and read until succesful
* 
* Summary:
*
* BOOLEAN fl_establish_media(driveno)
*
*
* Inputs:
*   int  driveno      - 0 or 1 = a: b:
*
* Returns:
*   TRUE on success else FALSE.
*   
* For each possible media type for this drive type in the devparms table. 
* Set the data rate, recal ,seek and read sector ID information from the
* drive. If the read ID works return TRUE. If all possible media are exhausted
* return FALSE.
*
* NOTE: The floppy change line is cleared by the seek operations.
*/

BOOLEAN fl_establish_media(int  driveno)                        /*__fn__*/
{
int i;
COMMAND_BLOCK b;

    /* Find the first drive description entry for the drive type */
    for (i = 0; fl_devparms[i].drive_type; i++)
    {
        if (fl_devparms[i].drive_type == floppy[driveno].drive_type)
            break;
    }
    /* Now scan through all drive descriptions for this drive type until
      we get get one we can read */
    while (fl_devparms[i].drive_type == floppy[driveno].drive_type)
    {
        /* Copy params from the drive table to the device */
        fl_cp_parms(driveno, i);
        /* Set the data rate */
        fl_write_drr(floppy[driveno].data_rate);
        if (fl_specify(driveno))
        {
            fl_motor_on(driveno);
            if (fl_recalibrate(driveno))
            {
                /* read sector markers. if we get a normal terminaton we're ok */
                fl_motor_on(driveno);
                /* See if we can read the sector ID field */
                if (fl_read_id(driveno, &b))
                {
                    if ((b.results[0] & (BIT6|BIT7)) == 0)
                    {
                        /* Now we seek to cyl 2 and back to zero. This will 
                           clear the change line if needed */
                        fl_motor_on(driveno);
                        if (!(fl_seek(driveno, 2, 0) && fl_seek(driveno, 0, 0)))
                            break;
                        else
                            return(TRUE);
                    }
                }
            }
        }
        i++;
    }
    floppy[driveno].media_type = DT_NONE;
    return(fl_report_error(FLERR_MEDIA, FALSE));
}

/*  fl_sense_interrupt - Issue a sense interrupt command
* 
* Summary:
*
* BOOLEAN fl_sense_interrupt(COMMAND_BLOCK *p)
*
*
* Inputs:
*   COMMAND_BLOCK *p - storage area. On return the results[0,1,2] will contain
*                      status registers 0,1,2
*
* Returns:
*   TRUE on success else FALSE.
*   
* This routine issues a sense interrupt command. It is called after
* seeks/recals and resets. The status registers are interpreted by
* the calling routine
*
*/

static BOOLEAN fl_sense_interrupt(COMMAND_BLOCK *p)                      /*__fn__*/
{
    p->n_to_send = 1;       
    p->n_to_get = 2;
    p->commands[0] = FL_SENSE_INTERRUPT;
    /* commands to the chip (always) */
    if (fl_command_phase(p))
        return(fl_results_phase(p));
    return(FALSE);
}

/*  fl_read_id - Read sector ID 
* 
* Summary:
*
* BOOLEAN fl_read_id(int  driveno, COMMAND_BLOCK *p)
*
*
* Inputs:
*   int  driveno      - 0 or 1 = a: b:
*   COMMAND_BLOCK *p - storage area. On return the results[0,1,N] will
*                      be valid.
*
* Returns:
*   TRUE on success else FALSE.
*   
* This routine is called by fl_establish_media. If the data rate is set
* right this routine should work. If it does work we know what the 
* installed media is. fl_establish_media checks the return codes in the
* status registers.
*
*/

static BOOLEAN fl_read_id(int  driveno, COMMAND_BLOCK *p)              /*__fn__*/
{
    p->n_to_send = 2;       
    p->n_to_get = 7;
    p->commands[0] = MFMBIT|FL_READID;
    p->commands[1] = (byte) driveno; 

    /* Clear any outstanding interrupt complete messages */
    OS_FLOPPY_SIGNAL_BIND(0);
    OS_FLOPPY_SIGNAL_CLEAR(0);

    /* commands to the chip (always) */
    if (fl_command_phase(p))
    {
        if (fl_waitint((int)FLTMO_READID))
            return(fl_results_phase(p));
    }

    return(FALSE);
}

/*  fl_seek - Seek to cylinder/head
* 
* Summary:
* BOOLEAN fl_seek(int  driveno, word cyl, word head)
*
*
* Inputs:
*   int  driveno      - 0 or 1 = a: b:
*   word cyl
*   word head
*
* Returns:
*   TRUE on success else FALSE.
*   
* This routine issues a seek waits for an interupt and then checks
* the status by issueing a sense interupt command. If all went
* well it returns TRUE.
*
*/

static BOOLEAN fl_seek(int  driveno, word cyl, word head)          /*__fn__*/
{
COMMAND_BLOCK b;

//AM: Only seek if moving to different track.  In that case, recalibrate.
//AM: You may speed up floppy by removing the recalibrate call which was inserted
//AM: to remedy problems with certain floppy controllers.  
#if (0)
// Removed because it was causing problems
   if ((cyl == floppy[driveno].last_cyl) && (head == floppy[driveno].last_head))
      return(TRUE);
   fl_recalibrate(driveno);
#endif
    
    b.n_to_send = 3;       
    b.n_to_get = 0;
    b.commands[0] = FL_SEEK;
    b.commands[1] = (byte) ((head<<2)| ((byte) driveno));
    b.commands[2] = (byte) cyl;

    /* Clear any outstanding interrupt complete messages */
    OS_FLOPPY_SIGNAL_BIND(0);
    OS_FLOPPY_SIGNAL_CLEAR(0);

    if (fl_command_phase(&b))
    {
        if (fl_waitint((int)FLTMO_SEEK))
        {
            if (fl_sense_interrupt(&b))
            {
                /* Should have BIT5 (seek end == 1) and bits 6 & 7 == 0 
                   the cylinder should be the same as passed in */           
                if ( ((b.results[0] & (BIT5|BIT6|BIT7)) == BIT5) &&
                     (b.results[1] == (byte) cyl) )
                     {
                     //AM: save information for last successful seek so will know
                     //AM: to recalibrate if seeking new cylinder/head.
                     floppy[driveno].last_cyl = (byte)cyl;     
                     floppy[driveno].last_head = (byte)head;
                     return(TRUE);
                     }
            }
        }
    }

    return(FALSE);
}

⌨️ 快捷键说明

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