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

📄 disk.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        return -EINVAL;
    
    info->connected = false;
    chan->valid     = false;
     
    // clear partition data and invalidate 
    // any allocated devices
    for (i = 0; i < MBR_PART_NUM; i++)
    {
        info->partitions[i].type = 0x00;

        if (0 != info->devs[i])
        {
            struct cyg_devtab_entry *dtab;
            disk_channel            *dchan;

            dtab  = (struct cyg_devtab_entry *)info->devs[i];
            dchan = (disk_channel *) dtab->priv;
            
            dchan->valid = false;
        }
    }

    
    D(("disk disconnected\n")); 

    return ENOERR;    
}
    
static Cyg_ErrNo
disk_lookup(struct cyg_devtab_entry **tab,
            struct cyg_devtab_entry  *sub_tab,
            const char *name)
{
    disk_channel    *chan = (disk_channel *) (*tab)->priv;
    cyg_disk_info_t *info = chan->info;
    struct cyg_devtab_entry *new_tab;
    disk_channel            *new_chan;
    int dev_num;
    
    if (!info->connected || name[0] < '0' || name[0] > '4' || '\0' != name[1])
        return -EINVAL;

    dev_num = name[0] - '0';

    D(("disk lookup dev number = %d\n", dev_num)); 

    if (0 == dev_num)
    {
        // 0 is the root device number
        return ENOERR; 
    }
    if (0x00 == info->partitions[dev_num-1].type)
    {
        D(("disk NO partition for dev\n")); 
        return -EINVAL;
    }
    
    if (0 == info->devs[dev_num-1])
    {
        D(("disk creating new devtab entry\n")); 

        // alloc mem for new device
        new_tab = (struct cyg_devtab_entry *)
            malloc(sizeof(struct cyg_devtab_entry));
        if (NULL == new_tab)
            return -ENOMEM;        

        // alloc mem for new device private data
        new_chan = (disk_channel *)malloc(sizeof(disk_channel));
        if (NULL == new_chan)
        {
            free(new_tab);
            return -ENOMEM;
        }
    }
    else
    {
        new_tab  = (struct cyg_devtab_entry *) info->devs[dev_num-1]; 
        new_chan = (disk_channel *) new_tab->priv;   
    }
    
    // copy device data from parent
    *new_tab  = **tab; 
    *new_chan = *chan;

    new_tab->priv = (void *)new_chan;

    // set partition ptr and put this device into devices array    
    new_chan->partition = &info->partitions[dev_num-1];
    chan->info->devs[dev_num-1] = (cyg_addrword_t) new_tab;

    // return device tab 
    *tab = new_tab;
        
    return ENOERR;
}

// ---------------------------------------------------------------------------

static Cyg_ErrNo 
disk_bread(cyg_io_handle_t  handle, 
           void            *buf, 
           cyg_uint32      *len,
           cyg_uint32       pos)
{
    cyg_devtab_entry_t *t    = (cyg_devtab_entry_t *) handle;
    disk_channel       *chan = (disk_channel *) t->priv;
    disk_funs          *funs = chan->funs;
    cyg_disk_info_t    *info = chan->info;
    cyg_uint32  size = *len;
    cyg_uint8  *bbuf = (cyg_uint8  *)buf;
    Cyg_ErrNo   res  = ENOERR;
    cyg_uint32  last;

    if (!info->connected || !chan->valid)
        return -EINVAL;
    
    if (NULL != chan->partition)
    {
        pos += chan->partition->start;
        last = chan->partition->end;
    }
    else
    {
        last = info->blocks_num-1;
    }
 
    D(("disk read block=%d len=%d buf=%p\n", pos, *len, buf)); 
 
    while (size > 0)
    {
        if (pos > last)
        {
            res = -EIO;
            break;
        }
        
        res = (funs->read)(chan, (void*)bbuf, info->block_size, pos);
        if (ENOERR != res)
            break;

        if (!info->connected)
        {
            res = -EINVAL;
            break;
        }
            
        bbuf += info->block_size;
        pos++;
        size--;
    }
    *len -= size;
    return res;
}

// ---------------------------------------------------------------------------

static Cyg_ErrNo 
disk_bwrite(cyg_io_handle_t  handle, 
            const void      *buf, 
            cyg_uint32      *len,
            cyg_uint32       pos)
{
    cyg_devtab_entry_t *t    = (cyg_devtab_entry_t *) handle;
    disk_channel       *chan = (disk_channel *) t->priv;
    disk_funs          *funs = chan->funs;
    cyg_disk_info_t    *info = chan->info;
    cyg_uint32  size = *len;
    cyg_uint8  *bbuf = (cyg_uint8 * const) buf;
    Cyg_ErrNo   res  = ENOERR;
    cyg_uint32  last;

    if (!info->connected || !chan->valid)
        return -EINVAL;
 
    if (NULL != chan->partition)
    {
        pos += chan->partition->start;
        last = chan->partition->end;
    }
    else
    {
        last = info->blocks_num-1;
    }
    
    D(("disk write block=%d len=%d buf=%p\n", pos, *len, buf)); 
   
    while (size > 0)
    {
        if (pos > last)
        {
            res = -EIO;
            break;
        }
        
        res = (funs->write)(chan, (void*)bbuf, info->block_size, pos);
        if (ENOERR != res)
            break;
 
        if (!info->connected)
        {
            res = -EINVAL;
            break;
        }
 
        bbuf += info->block_size;
        pos++;
        size--;
    }
    *len -= size;
    return res;
}

// ---------------------------------------------------------------------------

static cyg_bool
disk_select(cyg_io_handle_t handle, cyg_uint32 which, CYG_ADDRWORD info)
{
    cyg_devtab_entry_t *t     = (cyg_devtab_entry_t *) handle;
    disk_channel       *chan  = (disk_channel *) t->priv;
    cyg_disk_info_t    *cinfo = chan->info;
 
    if (!cinfo->connected || !chan->valid)
        return false;
    else
        return true;
}

// ---------------------------------------------------------------------------

static Cyg_ErrNo 
disk_get_config(cyg_io_handle_t  handle, 
                cyg_uint32       key, 
                void            *xbuf,
                cyg_uint32      *len)
{
    cyg_devtab_entry_t *t    = (cyg_devtab_entry_t *) handle;
    disk_channel       *chan = (disk_channel *) t->priv;
    cyg_disk_info_t    *info = chan->info;
    cyg_disk_info_t    *buf  = (cyg_disk_info_t *) xbuf;
    disk_funs          *funs = chan->funs;
    Cyg_ErrNo res = ENOERR;
 
    if (!info->connected || !chan->valid)
        return -EINVAL;

    D(("disk get config key=%d\n", key)); 
    
    switch (key) {
    case CYG_IO_GET_CONFIG_DISK_INFO:
        if (*len < sizeof(cyg_disk_info_t)) {
            return -EINVAL;
        }
        *buf = *chan->info;
        *len = sizeof(cyg_disk_info_t);
        break;       

    default:
        // pass down to lower layers
        res = (funs->get_config)(chan, key, xbuf, len);
    }
   
    return res;
}

// ---------------------------------------------------------------------------

static Cyg_ErrNo 
disk_set_config(cyg_io_handle_t  handle, 
                cyg_uint32       key, 
                const void      *xbuf, 
                cyg_uint32      *len)
{
    cyg_devtab_entry_t *t    = (cyg_devtab_entry_t *) handle;
    disk_channel       *chan = (disk_channel *) t->priv;
    cyg_disk_info_t    *info = chan->info;
    disk_funs          *funs = chan->funs;

    if (!info->connected || !chan->valid)
        return -EINVAL;

    D(("disk set config key=%d\n", key)); 
 
    // pass down to lower layers
    return (funs->set_config)(chan, key, xbuf, len);
}

// ---------------------------------------------------------------------------
// EOF disk.c

⌨️ 快捷键说明

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