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

📄 usbdcore.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
{	return (device->status == USB_STATUS_HALT);}/** * usbd_rcv_complete - complete a receive * @endpoint: * @len: * @urb_bad: * * Called from rcv interrupt to complete. */void usbd_rcv_complete(struct usb_endpoint_instance *endpoint, int len, int urb_bad){	if (endpoint) {		struct urb *rcv_urb;		/*usbdbg("len: %d urb: %p\n", len, endpoint->rcv_urb); */		/* if we had an urb then update actual_length, dispatch if neccessary */		if ((rcv_urb = endpoint->rcv_urb)) {			/*usbdbg("actual: %d buffer: %d\n", */			/*rcv_urb->actual_length, rcv_urb->buffer_length); */			/* check the urb is ok, are we adding data less than the packetsize */			if (!urb_bad && (len <= endpoint->rcv_packetSize)) {			  /*usbdbg("updating actual_length by %d\n",len); */				/* increment the received data size */				rcv_urb->actual_length += len;			} else {				usberr(" RECV_ERROR actual: %d buffer: %d urb_bad: %d\n",				       rcv_urb->actual_length, rcv_urb->buffer_length, urb_bad);				rcv_urb->actual_length = 0;				rcv_urb->status = RECV_ERROR;			}		} else {			usberr("no rcv_urb!");		}	} else {		usberr("no endpoint!");	}}/** * usbd_tx_complete - complete a transmit * @endpoint: * @resetart: * * Called from tx interrupt to complete. */void usbd_tx_complete (struct usb_endpoint_instance *endpoint){	if (endpoint) {		struct urb *tx_urb;		/* if we have a tx_urb advance or reset, finish if complete */		if ((tx_urb = endpoint->tx_urb)) {			int sent = endpoint->last;			endpoint->sent += sent;			endpoint->last -= sent;			if( (endpoint->tx_urb->actual_length - endpoint->sent) <= 0 ) {				tx_urb->actual_length = 0;				endpoint->sent = 0;				endpoint->last = 0;				/* Remove from active, save for re-use */				urb_detach(tx_urb);				urb_append(&endpoint->done, tx_urb);				/*usbdbg("done->next %p, tx_urb %p, done %p", */				/*	 endpoint->done.next, tx_urb, &endpoint->done); */				endpoint->tx_urb = first_urb_detached(&endpoint->tx);				if( endpoint->tx_urb ) {					endpoint->tx_queue--;					usbdbg("got urb from tx list");				}				if( !endpoint->tx_urb ) {					/*usbdbg("taking urb from done list"); */					endpoint->tx_urb = first_urb_detached(&endpoint->done);				}				if( !endpoint->tx_urb ) {					usbdbg("allocating new urb for tx_urb");					endpoint->tx_urb = usbd_alloc_urb(tx_urb->device, endpoint);				}			}		}	}}/* URB linked list functions ***************************************************** *//* * Initialize an urb_link to be a single element list. * If the urb_link is being used as a distinguished list head * the list is empty when the head is the only link in the list. */void urb_link_init (urb_link * ul){	if (ul) {		ul->prev = ul->next = ul;	}}/* * Detach an urb_link from a list, and set it * up as a single element list, so no dangling * pointers can be followed, and so it can be * joined to another list if so desired. */void urb_detach (struct urb *urb){	if (urb) {		urb_link *ul = &urb->link;		ul->next->prev = ul->prev;		ul->prev->next = ul->next;		urb_link_init (ul);	}}/* * Return the first urb_link in a list with a distinguished * head "hd", or NULL if the list is empty.  This will also * work as a predicate, returning NULL if empty, and non-NULL * otherwise. */urb_link *first_urb_link (urb_link * hd){	urb_link *nx;	if (NULL != hd && NULL != (nx = hd->next) && nx != hd) {		/* There is at least one element in the list */		/* (besides the distinguished head). */		return (nx);	}	/* The list is empty */	return (NULL);}/* * Return the first urb in a list with a distinguished * head "hd", or NULL if the list is empty. */struct urb *first_urb (urb_link * hd){	urb_link *nx;	if (NULL == (nx = first_urb_link (hd))) {		/* The list is empty */		return (NULL);	}	return (p2surround (struct urb, link, nx));}/* * Detach and return the first urb in a list with a distinguished * head "hd", or NULL if the list is empty. * */struct urb *first_urb_detached (urb_link * hd){	struct urb *urb;	if ((urb = first_urb (hd))) {		urb_detach (urb);	}	return urb;}/* * Append an urb_link (or a whole list of * urb_links) to the tail of another list * of urb_links. */void urb_append (urb_link * hd, struct urb *urb){	if (hd && urb) {		urb_link *new = &urb->link;		/* This allows the new urb to be a list of urbs, */		/* with new pointing at the first, but the link */		/* must be initialized. */		/* Order is important here... */		urb_link *pul = hd->prev;		new->prev->next = hd;		hd->prev = new->prev;		new->prev = pul;		pul->next = new;	}}/* URB create/destroy functions ***************************************************** *//** * usbd_alloc_urb - allocate an URB appropriate for specified endpoint * @device: device instance * @endpoint: endpoint * * Allocate an urb structure. The usb device urb structure is used to * contain all data associated with a transfer, including a setup packet for * control transfers. * * NOTE: endpoint_address MUST contain a direction flag. */struct urb *usbd_alloc_urb (struct usb_device_instance *device, struct usb_endpoint_instance *endpoint){	struct urb *urb;	if( !(urb = (struct urb*)malloc(sizeof(struct urb))) ) {	  usberr(" F A T A L:  malloc(%u) FAILED!!!!", sizeof(struct urb));	  return NULL;	}	/* Fill in known fields */	memset(urb, 0, sizeof(struct urb));	urb->endpoint = endpoint;	urb->device = device;	urb->buffer = (u8*)urb->buffer_data;	urb->buffer_length = sizeof(urb->buffer_data);	urb_link_init (&urb->link);	return urb;}/** * usbd_dealloc_urb - deallocate an URB and associated buffer * @urb: pointer to an urb structure * * Deallocate an urb structure and associated data. */void usbd_dealloc_urb (struct urb *urb){	if (urb) {		free (urb);	}}/* Event signaling functions ***************************************************** *//** * usbd_device_event - called to respond to various usb events * @device: pointer to struct device * @event: event to respond to * * Used by a Bus driver to indicate an event. */void usbd_device_event_irq (struct usb_device_instance *device, usb_device_event_t event, int data){	usb_device_state_t state;	if (!device || !device->bus) {		usberr("(%p,%d) NULL device or device->bus", device, event);		return;	}	state = device->device_state;	usbinfo("%s", usbd_device_events[event]);	switch (event) {	case DEVICE_UNKNOWN:		break;	case DEVICE_INIT:		device->device_state = STATE_INIT;		break;	case DEVICE_CREATE:		device->device_state = STATE_ATTACHED;		break;	case DEVICE_HUB_CONFIGURED:		device->device_state = STATE_POWERED;		break;	case DEVICE_RESET:		device->device_state = STATE_DEFAULT;		device->address = 0;		break;	case DEVICE_ADDRESS_ASSIGNED:		device->device_state = STATE_ADDRESSED;		break;	case DEVICE_CONFIGURED:		device->device_state = STATE_CONFIGURED;		break;	case DEVICE_DE_CONFIGURED:		device->device_state = STATE_ADDRESSED;		break;	case DEVICE_BUS_INACTIVE:		if (device->status != USBD_CLOSING) {			device->status = USBD_SUSPENDED;		}		break;	case DEVICE_BUS_ACTIVITY:		if (device->status != USBD_CLOSING) {			device->status = USBD_OK;		}		break;	case DEVICE_SET_INTERFACE:		break;	case DEVICE_SET_FEATURE:		break;	case DEVICE_CLEAR_FEATURE:		break;	case DEVICE_POWER_INTERRUPTION:		device->device_state = STATE_POWERED;		break;	case DEVICE_HUB_RESET:		device->device_state = STATE_ATTACHED;		break;	case DEVICE_DESTROY:		device->device_state = STATE_UNKNOWN;		break;	case DEVICE_FUNCTION_PRIVATE:		break;	default:		usbdbg("event %d - not handled",event);		break;	}	/*usbdbg("%s event: %d oldstate: %d newstate: %d status: %d address: %d",		device->name, event, state,		device->device_state, device->status, device->address); */	/* tell the bus interface driver */	if( device->event ) {		/* usbdbg("calling device->event"); */		device->event(device, event, data);	}}

⌨️ 快捷键说明

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