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

📄 cs.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 5 页
字号:
	(req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)))	return CS_BAD_ATTRIBUTE;    if (alloc_io_space(s, req->Attributes1, &req->BasePort1,		       req->NumPorts1, req->IOAddrLines,		       handle->dev_info))	return CS_IN_USE;    if (req->NumPorts2) {	if (alloc_io_space(s, req->Attributes2, &req->BasePort2,			   req->NumPorts2, req->IOAddrLines,			   handle->dev_info)) {	    release_io_space(s, req->BasePort1, req->NumPorts1);	    return CS_IN_USE;	}    }    c->io = *req;    c->state |= CONFIG_IO_REQ;    handle->state |= CLIENT_IO_REQ;    return CS_SUCCESS;} /* request_io *//*======================================================================    Request_irq() reserves an irq for this client.    Also, since Linux only reserves irq's when they are actually    hooked, we don't guarantee that an irq will still be available    when the configuration is locked.  Now that I think about it,    there might be a way to fix this using a dummy handler.    ======================================================================*/int pcmcia_request_irq(client_handle_t handle, irq_req_t *req){    socket_info_t *s;    config_t *c;    int ret = 0, irq = 0;        if (CHECK_HANDLE(handle))	return CS_BAD_HANDLE;    s = SOCKET(handle);    if (!(s->state & SOCKET_PRESENT))	return CS_NO_CARD;    c = CONFIG(handle);    if (c->state & CONFIG_LOCKED)	return CS_CONFIGURATION_LOCKED;    if (c->state & CONFIG_IRQ_REQ)	return CS_IN_USE;        /* Short cut: if there are no ISA interrupts, then it is PCI */    if (!s->cap.irq_mask) {	irq = s->cap.pci_irq;	ret = (irq) ? 0 : CS_IN_USE;#ifdef CONFIG_ISA    } else if (s->irq.AssignedIRQ != 0) {	/* If the interrupt is already assigned, it must match */	irq = s->irq.AssignedIRQ;	if (req->IRQInfo1 & IRQ_INFO2_VALID) {	    u_int mask = req->IRQInfo2 & s->cap.irq_mask;	    ret = ((mask >> irq) & 1) ? 0 : CS_BAD_ARGS;	} else	    ret = ((req->IRQInfo1&IRQ_MASK) == irq) ? 0 : CS_BAD_ARGS;    } else {	ret = CS_IN_USE;	if (req->IRQInfo1 & IRQ_INFO2_VALID) {	    u_int try, mask = req->IRQInfo2 & s->cap.irq_mask;	    for (try = 0; try < 2; try++) {		for (irq = 0; irq < 32; irq++)		    if ((mask >> irq) & 1) {			ret = try_irq(req->Attributes, irq, try);			if (ret == 0) break;		    }		if (ret == 0) break;	    }	} else {	    irq = req->IRQInfo1 & IRQ_MASK;	    ret = try_irq(req->Attributes, irq, 1);	}#endif    }    if (ret != 0) return ret;    if (req->Attributes & IRQ_HANDLE_PRESENT) {	if (bus_request_irq(s->cap.bus, irq, req->Handler,			    ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) || 			     (s->functions > 1) ||			     (irq == s->cap.pci_irq)) ? SA_SHIRQ : 0,			    handle->dev_info, req->Instance))	    return CS_IN_USE;    }    c->irq.Attributes = req->Attributes;    s->irq.AssignedIRQ = req->AssignedIRQ = irq;    s->irq.Config++;        c->state |= CONFIG_IRQ_REQ;    handle->state |= CLIENT_IRQ_REQ;    return CS_SUCCESS;} /* pcmcia_request_irq *//*======================================================================    Request_window() establishes a mapping between card memory space    and system memory space.======================================================================*/int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle_t *wh){    socket_info_t *s;    window_t *win;    u_long align;    int w;        if (CHECK_HANDLE(*handle))	return CS_BAD_HANDLE;    s = SOCKET(*handle);    if (!(s->state & SOCKET_PRESENT))	return CS_NO_CARD;    if (req->Attributes & (WIN_PAGED | WIN_SHARED))	return CS_BAD_ATTRIBUTE;    /* Window size defaults to smallest available */    if (req->Size == 0)	req->Size = s->cap.map_size;    align = (((s->cap.features & SS_CAP_MEM_ALIGN) ||	      (req->Attributes & WIN_STRICT_ALIGN)) ?	     req->Size : s->cap.map_size);    if (req->Size & (s->cap.map_size-1))	return CS_BAD_SIZE;    if ((req->Base && (s->cap.features & SS_CAP_STATIC_MAP)) ||	(req->Base & (align-1)))	return CS_BAD_BASE;    if (req->Base)	align = 0;    /* Allocate system memory window */    for (w = 0; w < MAX_WIN; w++)	if (!(s->state & SOCKET_WIN_REQ(w))) break;    if (w == MAX_WIN)	return CS_OUT_OF_RESOURCE;    win = &s->win[w];    win->magic = WINDOW_MAGIC;    win->index = w;    win->handle = *handle;    win->sock = s;    win->base = req->Base;    win->size = req->Size;    if (!(s->cap.features & SS_CAP_STATIC_MAP) &&	find_mem_region(&win->base, win->size, align,			(req->Attributes & WIN_MAP_BELOW_1MB) ||			!(s->cap.features & SS_CAP_PAGE_REGS),			(*handle)->dev_info))	return CS_IN_USE;    (*handle)->state |= CLIENT_WIN_REQ(w);    /* Configure the socket controller */    win->ctl.map = w+1;    win->ctl.flags = 0;    win->ctl.speed = req->AccessSpeed;    if (req->Attributes & WIN_MEMORY_TYPE)	win->ctl.flags |= MAP_ATTRIB;    if (req->Attributes & WIN_ENABLE)	win->ctl.flags |= MAP_ACTIVE;    if (req->Attributes & WIN_DATA_WIDTH_16)	win->ctl.flags |= MAP_16BIT;    if (req->Attributes & WIN_USE_WAIT)	win->ctl.flags |= MAP_USE_WAIT;    win->ctl.sys_start = win->base;    win->ctl.sys_stop = win->base + win->size-1;    win->ctl.card_start = 0;    if (set_mem_map(s, &win->ctl) != 0)	return CS_BAD_ARGS;    s->state |= SOCKET_WIN_REQ(w);    /* Return window handle */    req->Base = win->ctl.sys_start;    *wh = win;        return CS_SUCCESS;} /* request_window *//*======================================================================    I'm not sure which "reset" function this is supposed to use,    but for now, it uses the low-level interface's reset, not the    CIS register.    ======================================================================*/int pcmcia_reset_card(client_handle_t handle, client_req_t *req){    int i, ret;    socket_info_t *s;        if (CHECK_HANDLE(handle))	return CS_BAD_HANDLE;    i = handle->Socket; s = socket_table[i];    if (!(s->state & SOCKET_PRESENT))	return CS_NO_CARD;    if (s->state & SOCKET_RESET_PENDING)	return CS_IN_USE;    s->state |= SOCKET_RESET_PENDING;    ret = send_event(s, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW);    if (ret != 0) {	s->state &= ~SOCKET_RESET_PENDING;	handle->event_callback_args.info = (void *)(u_long)ret;	EVENT(handle, CS_EVENT_RESET_COMPLETE, CS_EVENT_PRI_LOW);    } else {	DEBUG(1, "cs: resetting socket %d\n", i);	send_event(s, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);	s->reset_handle = handle;	reset_socket(s);    }    return CS_SUCCESS;} /* reset_card *//*======================================================================    These shut down or wake up a socket.  They are sort of user    initiated versions of the APM suspend and resume actions.    ======================================================================*/int pcmcia_suspend_card(client_handle_t handle, client_req_t *req){    int i;    socket_info_t *s;        if (CHECK_HANDLE(handle))	return CS_BAD_HANDLE;    i = handle->Socket; s = socket_table[i];    if (!(s->state & SOCKET_PRESENT))	return CS_NO_CARD;    if (s->state & SOCKET_SUSPEND)	return CS_IN_USE;    DEBUG(1, "cs: suspending socket %d\n", i);    send_event(s, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);    suspend_socket(s);    s->state |= SOCKET_SUSPEND;    return CS_SUCCESS;} /* suspend_card */int pcmcia_resume_card(client_handle_t handle, client_req_t *req){    int i;    socket_info_t *s;        if (CHECK_HANDLE(handle))	return CS_BAD_HANDLE;    i = handle->Socket; s = socket_table[i];    if (!(s->state & SOCKET_PRESENT))	return CS_NO_CARD;    if (!(s->state & SOCKET_SUSPEND))	return CS_IN_USE;    DEBUG(1, "cs: waking up socket %d\n", i);    setup_socket(s);    return CS_SUCCESS;} /* resume_card *//*======================================================================    These handle user requests to eject or insert a card.    ======================================================================*/int pcmcia_eject_card(client_handle_t handle, client_req_t *req){    int i, ret;    socket_info_t *s;    u_long flags;        if (CHECK_HANDLE(handle))	return CS_BAD_HANDLE;    i = handle->Socket; s = socket_table[i];    if (!(s->state & SOCKET_PRESENT))	return CS_NO_CARD;    DEBUG(1, "cs: user eject request on socket %d\n", i);    ret = send_event(s, CS_EVENT_EJECTION_REQUEST, CS_EVENT_PRI_LOW);    if (ret != 0)	return ret;    spin_lock_irqsave(&s->lock, flags);    do_shutdown(s);    spin_unlock_irqrestore(&s->lock, flags);        return CS_SUCCESS;    } /* eject_card */int pcmcia_insert_card(client_handle_t handle, client_req_t *req){    int i, status;    socket_info_t *s;    u_long flags;        if (CHECK_HANDLE(handle))	return CS_BAD_HANDLE;    i = handle->Socket; s = socket_table[i];    if (s->state & SOCKET_PRESENT)	return CS_IN_USE;    DEBUG(1, "cs: user insert request on socket %d\n", i);    spin_lock_irqsave(&s->lock, flags);    if (!(s->state & SOCKET_SETUP_PENDING)) {	s->state |= SOCKET_SETUP_PENDING;	spin_unlock_irqrestore(&s->lock, flags);	get_socket_status(s, &status);	if ((status & SS_DETECT) == 0 || (setup_socket(s) == 0)) {	    s->state &= ~SOCKET_SETUP_PENDING;	    return CS_NO_CARD;	}    } else	spin_unlock_irqrestore(&s->lock, flags);    return CS_SUCCESS;} /* insert_card *//*======================================================================    Maybe this should send a CS_EVENT_CARD_INSERTION event if we    haven't sent one to this client yet?    ======================================================================*/int pcmcia_set_event_mask(client_handle_t handle, eventmask_t *mask){    u_int events, bit;    if (CHECK_HANDLE(handle))	return CS_BAD_HANDLE;    if (handle->Attributes & CONF_EVENT_MASK_VALID)	return CS_BAD_SOCKET;    handle->EventMask = mask->EventMask;    events = handle->PendingEvents & handle->EventMask;    handle->PendingEvents -= events;    while (events != 0) {	bit = ((events ^ (events-1)) + 1) >> 1;	EVENT(handle, bit, CS_EVENT_PRI_LOW);	events -= bit;    }    return CS_SUCCESS;} /* set_event_mask *//*====================================================================*/int pcmcia_report_error(client_handle_t handle, error_info_t *err){    int i;    char *serv;    if (CHECK_HANDLE(handle))	printk(KERN_NOTICE);    else	printk(KERN_NOTICE "%s: ", handle->dev_info);        for (i = 0; i < SERVICE_COUNT; i++)	if (service_table[i].key == err->func) break;    if (i < SERVICE_COUNT)	serv = service_table[i].msg;    else	serv = "Unknown service number";    for (i = 0; i < ERROR_COUNT; i++)	if (error_table[i].key == err->retcode) break;    if (i < ERROR_COUNT)	printk("%s: %s\n", serv, error_table[i].msg);    else	printk("%s: Unknown error code %#x\n", serv, err->retcode);    return CS_SUCCESS;} /* report_error *//*====================================================================*/int CardServices(int func, void *a1, void *a2, void *a3){#ifdef PCMCIA_DEBUG    if (pc_debug > 2) {	int i;	for (i = 0; i < SERVICE_COUNT; i++)	    if (service_table[i].key == func) break;	if (i < SERVICE_COUNT)	    printk(KERN_DEBUG "cs: CardServices(%s, 0x%p, 0x%p)\n",		   service_table[i].msg, a1, a2);	else	    printk(KERN_DEBUG "cs: CardServices(Unknown func %d, "		   "0x%p, 0x%p)\n", func, a1, a2);    }#endif    switch (func) {    case AccessConfigurationRegister:	return pcmcia_access_configuration_register(a1, a2); break;    case AdjustResourceInfo:	return pcmcia_adjust_resource_info(a1, a2); break;    case CheckEraseQueue:	return pcmcia_check_erase_queue(a1); break;    case CloseMemory:	return pcmcia_close_memory(a1); break;    case CopyMemory:	return pcmcia_copy_memory(a1, a2); break;    case DeregisterClient:	return pcmcia_deregister_client(a1); break;    case DeregisterEraseQueue:	return pcmcia_deregister_erase_queue(a1); break;    case GetFirstClient:	return pcmcia_get_first_client(a1, a2); break;    case GetCardServicesInfo:	return pcmcia_get_card_services_info(a1); break;    case GetConfigurationInfo:	return pcmcia_get_configuration_info(a1, a2); break;    case GetNextClient:	return pcmcia_get_next_client(a1, a2); break;    case GetFirstRegion:	return pcmcia_get_first_region(a1, a2); break;    case GetFirstTuple:	return pcmcia_get_first_tuple(a1, a2); break;    case GetNextRegion:	return pcmcia_get_next_region(a1, a2); break;    case GetNextTuple:	return pcmcia_get_next_tuple(a1, a2); break;    case GetStatus:	return pcmcia_get_status(a1, a2); break;    case GetTupleData:	return pcmcia_get_tuple_data(a1, a2); break;    case MapMemPage:	return pcmcia_map_mem_page(a1, a2); break;    case ModifyConfiguration:	return pcmcia_modify_configuration(a1, a2); break;    case ModifyWindow:	return pcmcia_modify_window(a1, a2); break;    case OpenMemory:/*	return pcmcia_open_memory(a1, a2); */    {	memory

⌨️ 快捷键说明

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