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

📄 bulkmem.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 2 页
字号:
    This stuff is used by Card Services to initialize the table of    region info used for subsequent calls to GetFirstRegion and    GetNextRegion.    ======================================================================*/static void setup_regions(client_handle_t handle, int attr,			  memory_handle_t *list){    int i, code, has_jedec, has_geo;    u_int offset;    cistpl_device_t device;    cistpl_jedec_t jedec;    cistpl_device_geo_t geo;    memory_handle_t r;    DEBUG(1, "cs: setup_regions(0x%p, %d, 0x%p)\n",	  handle, attr, list);    code = (attr) ? CISTPL_DEVICE_A : CISTPL_DEVICE;    if (read_tuple(handle, code, &device) != CS_SUCCESS)	return;    code = (attr) ? CISTPL_JEDEC_A : CISTPL_JEDEC_C;    has_jedec = (read_tuple(handle, code, &jedec) == CS_SUCCESS);    if (has_jedec && (device.ndev != jedec.nid)) {#ifdef PCMCIA_DEBUG	printk(KERN_DEBUG "cs: Device info does not match JEDEC info.\n");#endif	has_jedec = 0;    }    code = (attr) ? CISTPL_DEVICE_GEO_A : CISTPL_DEVICE_GEO;    has_geo = (read_tuple(handle, code, &geo) == CS_SUCCESS);    if (has_geo && (device.ndev != geo.ngeo)) {#ifdef PCMCIA_DEBUG	printk(KERN_DEBUG "cs: Device info does not match geometry tuple.\n");#endif	has_geo = 0;    }        offset = 0;    for (i = 0; i < device.ndev; i++) {	if ((device.dev[i].type != CISTPL_DTYPE_NULL) &&	    (device.dev[i].size != 0)) {	    r = kmalloc(sizeof(*r), GFP_KERNEL);	    r->region_magic = REGION_MAGIC;	    r->state = 0;	    r->dev_info[0] = '\0';	    r->mtd = NULL;	    r->info.Attributes = (attr) ? REGION_TYPE_AM : 0;	    r->info.CardOffset = offset;	    r->info.RegionSize = device.dev[i].size;	    r->info.AccessSpeed = device.dev[i].speed;	    if (has_jedec) {		r->info.JedecMfr = jedec.id[i].mfr;		r->info.JedecInfo = jedec.id[i].info;	    } else		r->info.JedecMfr = r->info.JedecInfo = 0;	    if (has_geo) {		r->info.BlockSize = geo.geo[i].buswidth *		    geo.geo[i].erase_block * geo.geo[i].interleave;		r->info.PartMultiple =		    r->info.BlockSize * geo.geo[i].partition;	    } else		r->info.BlockSize = r->info.PartMultiple = 1;	    r->info.next = *list; *list = r;	}	offset += device.dev[i].size;    }} /* setup_regions *//*======================================================================    This is tricky.  When get_first_region() is called by Driver    Services, we initialize the region info table in the socket    structure.  When it is called by an MTD, we can just scan the    table for matching entries.    ======================================================================*/static int match_region(client_handle_t handle, memory_handle_t list,			region_info_t *match){    while (list != NULL) {	if (!(handle->Attributes & INFO_MTD_CLIENT) ||	    (strcmp(handle->dev_info, list->dev_info) == 0)) {	    *match = list->info;	    return CS_SUCCESS;	}	list = list->info.next;    }    return CS_NO_MORE_ITEMS;} /* match_region */int pcmcia_get_first_region(client_handle_t handle, region_info_t *rgn){    socket_info_t *s = SOCKET(handle);    if (CHECK_HANDLE(handle))	return CS_BAD_HANDLE;        if ((handle->Attributes & INFO_MASTER_CLIENT) &&	(!(s->state & SOCKET_REGION_INFO))) {	setup_regions(handle, 0, &s->c_region);	setup_regions(handle, 1, &s->a_region);	s->state |= SOCKET_REGION_INFO;    }    if (rgn->Attributes & REGION_TYPE_AM)	return match_region(handle, s->a_region, rgn);    else	return match_region(handle, s->c_region, rgn);} /* get_first_region */int pcmcia_get_next_region(client_handle_t handle, region_info_t *rgn){    if (CHECK_HANDLE(handle))	return CS_BAD_HANDLE;    return match_region(handle, rgn->next, rgn);} /* get_next_region *//*======================================================================    Connect an MTD with a memory region.    ======================================================================*/int pcmcia_register_mtd(client_handle_t handle, mtd_reg_t *reg){    memory_handle_t list;    socket_info_t *s;        if (CHECK_HANDLE(handle))	return CS_BAD_HANDLE;    s = SOCKET(handle);    if (reg->Attributes & REGION_TYPE_AM)	list = s->a_region;    else	list = s->c_region;    DEBUG(1, "cs: register_mtd(0x%p, '%s', 0x%x)\n",	  handle, handle->dev_info, reg->Offset);    while (list) {	if (list->info.CardOffset == reg->Offset) break;	list = list->info.next;    }    if (list && (list->mtd == NULL) &&	(strcmp(handle->dev_info, list->dev_info) == 0)) {	list->info.Attributes = reg->Attributes;	list->MediaID = reg->MediaID;	list->mtd = handle;	handle->mtd_count++;	return CS_SUCCESS;    } else	return CS_BAD_OFFSET;} /* register_mtd *//*======================================================================    Erase queue management functions    ======================================================================*/int pcmcia_register_erase_queue(client_handle_t *handle, eraseq_hdr_t *header,                                 eraseq_handle_t *e){    eraseq_t *queue;    if ((handle == NULL) || CHECK_HANDLE(*handle))	return CS_BAD_HANDLE;    queue = kmalloc(sizeof(*queue), GFP_KERNEL);    if (!queue) return CS_OUT_OF_RESOURCE;    queue->eraseq_magic = ERASEQ_MAGIC;    queue->handle = *handle;    queue->count = header->QueueEntryCnt;    queue->entry = header->QueueEntryArray;    *e = queue;    return CS_SUCCESS;} /* register_erase_queue */int pcmcia_deregister_erase_queue(eraseq_handle_t eraseq){    int i;    if (CHECK_ERASEQ(eraseq))	return CS_BAD_HANDLE;    for (i = 0; i < eraseq->count; i++)	if (ERASE_IN_PROGRESS(eraseq->entry[i].State)) break;    if (i < eraseq->count)	return CS_BUSY;    eraseq->eraseq_magic = 0;    kfree(eraseq);    return CS_SUCCESS;} /* deregister_erase_queue */int pcmcia_check_erase_queue(eraseq_handle_t eraseq){    int i;    if (CHECK_ERASEQ(eraseq))	return CS_BAD_HANDLE;    for (i = 0; i < eraseq->count; i++)	if (eraseq->entry[i].State == ERASE_QUEUED)	    setup_erase_request(eraseq->handle, &eraseq->entry[i]);    return CS_SUCCESS;} /* check_erase_queue *//*======================================================================    Look up the memory region matching the request, and return a    memory handle.    ======================================================================*/int pcmcia_open_memory(client_handle_t *handle, open_mem_t *open, memory_handle_t *mh){    socket_info_t *s;    memory_handle_t region;        if ((handle == NULL) || CHECK_HANDLE(*handle))	return CS_BAD_HANDLE;    s = SOCKET(*handle);    if (open->Attributes & MEMORY_TYPE_AM)	region = s->a_region;    else	region = s->c_region;    while (region) {	if (region->info.CardOffset == open->Offset) break;	region = region->info.next;    }    if (region && region->mtd) {	*mh = region;	DEBUG(1, "cs: open_memory(0x%p, 0x%x) = 0x%p\n",	      handle, open->Offset, region);	return CS_SUCCESS;    } else	return CS_BAD_OFFSET;} /* open_memory *//*======================================================================    Close a memory handle from an earlier call to OpenMemory.        For the moment, I don't think this needs to do anything.    ======================================================================*/int pcmcia_close_memory(memory_handle_t handle){    DEBUG(1, "cs: close_memory(0x%p)\n", handle);    if (CHECK_REGION(handle))	return CS_BAD_HANDLE;    return CS_SUCCESS;} /* close_memory *//*======================================================================    Read from a memory device, using a handle previously returned    by a call to OpenMemory.    ======================================================================*/int pcmcia_read_memory(memory_handle_t handle, mem_op_t *req, caddr_t buf){    mtd_request_t mtd;    if (CHECK_REGION(handle))	return CS_BAD_HANDLE;    if (req->Offset >= handle->info.RegionSize)	return CS_BAD_OFFSET;    if (req->Offset+req->Count > handle->info.RegionSize)	return CS_BAD_SIZE;        mtd.SrcCardOffset = req->Offset + handle->info.CardOffset;    mtd.TransferLength = req->Count;    mtd.MediaID = handle->MediaID;    mtd.Function = MTD_REQ_READ;    if (req->Attributes & MEM_OP_BUFFER_KERNEL)	mtd.Function |= MTD_REQ_KERNEL;    return do_mtd_request(handle, &mtd, buf);} /* read_memory *//*======================================================================    Write to a memory device, using a handle previously returned by    a call to OpenMemory.    ======================================================================*/int pcmcia_write_memory(memory_handle_t handle, mem_op_t *req, caddr_t buf){    mtd_request_t mtd;    if (CHECK_REGION(handle))	return CS_BAD_HANDLE;    if (req->Offset >= handle->info.RegionSize)	return CS_BAD_OFFSET;    if (req->Offset+req->Count > handle->info.RegionSize)	return CS_BAD_SIZE;        mtd.DestCardOffset = req->Offset + handle->info.CardOffset;    mtd.TransferLength = req->Count;    mtd.MediaID = handle->MediaID;    mtd.Function = MTD_REQ_WRITE;    if (req->Attributes & MEM_OP_BUFFER_KERNEL)	mtd.Function |= MTD_REQ_KERNEL;    return do_mtd_request(handle, &mtd, buf);} /* write_memory *//*======================================================================    This isn't needed for anything I could think of.    ======================================================================*/int pcmcia_copy_memory(memory_handle_t handle, copy_op_t *req){    if (CHECK_REGION(handle))	return CS_BAD_HANDLE;    return CS_UNSUPPORTED_FUNCTION;}

⌨️ 快捷键说明

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