📄 disk.c
字号:
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_ErrNodisk_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_booldisk_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 + -