kernels/linux-2.4.0/drivers/usb/uhci.c
/*
 * Return the result of a transfer
 *
 * Must be called with urblist_lock acquired
 */
Return the result of a transfer
Must be called with urblist_lock acquired
Return the result of a transfer Must be called with urblist_lock acquired
static void uhci_transfer_result(struct urb *urb)
{
	struct usb_device *dev = urb->dev;
	struct urb *turb;
	int proceed = 0, is_ring = 0;
	int ret = -EINVAL;
	unsigned long flags;
	spin_lock_irqsave(&urb->lock, flags);
	switch (usb_pipetype(urb->pipe)) {
	case PIPE_CONTROL:
		ret = uhci_result_control(urb);
		break;
	case PIPE_INTERRUPT:
		ret = uhci_result_interrupt(urb);
		break;
	case PIPE_BULK:
		ret = uhci_result_bulk(urb);
		break;
	case PIPE_ISOCHRONOUS:
		ret = uhci_result_isochronous(urb);
		break;
	}
	urb->status = ret;
	spin_unlock_irqrestore(&urb->lock, flags);
	if (ret == -EINPROGRESS)
		return;
	switch (usb_pipetype(urb->pipe)) {
	case PIPE_CONTROL:
	case PIPE_BULK:
	case PIPE_ISOCHRONOUS:
		if (urb->bandwidth)
			usb_release_bandwidth(urb->dev, urb, 1);
		uhci_unlink_generic(urb);
		break;
	case PIPE_INTERRUPT:
		if (urb->interval) {
			urb->complete(urb);
			uhci_reset_interrupt(urb);
			return;
		}
		if (urb->bandwidth)
			usb_release_bandwidth(urb->dev, urb, 0);
		uhci_unlink_generic(urb);
		break;
	}
	if (urb->next) {
		turb = urb->next;
		do {
			if (turb->status != -EINPROGRESS) {
				proceed = 1;
				break;
			}
			turb = turb->next;
		} while (turb && turb != urb && turb != urb->next);
		if (turb == urb || turb == urb->next)
			is_ring = 1;
	}
	if (urb->complete && !proceed) {
		urb->complete(urb);
		if (!proceed && is_ring)
			uhci_submit_urb(urb);
	}
	if (proceed && urb->next) {
		turb = urb->next;
		do {
			if (turb->status != -EINPROGRESS &&
			    uhci_submit_urb(turb) != 0)
			turb = turb->next;
		} while (turb && turb != urb->next);
		if (urb->complete)
			urb->complete(urb);
	}
	usb_dec_dev_use(dev);
}
static void uhci_transfer_result ( struct urb * urb ) { struct usb_device * dev = urb -> dev ; struct urb * turb ; int proceed = 0 , is_ring = 0 ; int ret = - EINVAL ; unsigned long flags ; spin_lock_irqsave ( & urb -> lock , flags ) ; switch ( usb_pipetype ( urb -> pipe ) ) { case PIPE_CONTROL : ret = uhci_result_control ( urb ) ; break ; case PIPE_INTERRUPT : ret = uhci_result_interrupt ( urb ) ; break ; case PIPE_BULK : ret = uhci_result_bulk ( urb ) ; break ; case PIPE_ISOCHRONOUS : ret = uhci_result_isochronous ( urb ) ; break ; } urb -> status = ret ; spin_unlock_irqrestore ( & urb -> lock , flags ) ; if ( ret == - EINPROGRESS ) return ; switch ( usb_pipetype ( urb -> pipe ) ) { case PIPE_CONTROL : case PIPE_BULK : case PIPE_ISOCHRONOUS : if ( urb -> bandwidth ) usb_release_bandwidth ( urb -> dev , urb , 1 ) ; uhci_unlink_generic ( urb ) ; break ; case PIPE_INTERRUPT : if ( urb -> interval ) { urb -> complete ( urb ) ; uhci_reset_interrupt ( urb ) ; return ; } if ( urb -> bandwidth ) usb_release_bandwidth ( urb -> dev , urb , 0 ) ; uhci_unlink_generic ( urb ) ; break ; } if ( urb -> next ) { turb = urb -> next ; do { if ( turb -> status != - EINPROGRESS ) { proceed = 1 ; break ; } turb = turb -> next ; } while ( turb && turb != urb && turb != urb -> next ) ; if ( turb == urb || turb == urb -> next ) is_ring = 1 ; } if ( urb -> complete && ! proceed ) { urb -> complete ( urb ) ; if ( ! proceed && is_ring ) uhci_submit_urb ( urb ) ; } if ( proceed && urb -> next ) { turb = urb -> next ; do { if ( turb -> status != - EINPROGRESS && uhci_submit_urb ( turb ) != 0 ) turb = turb -> next ; } while ( turb && turb != urb -> next ) ; if ( urb -> complete ) urb -> complete ( urb ) ; } usb_dec_dev_use ( dev ) ; }
Return the result of a transfer
 Must be called with urblist_lock acquired
Return the result of a transfer Must be called with urblist_lock acquired
/* Release bandwidth for Interrupt or Isoc. transfers */ /* Spinlock needed ? */ /* Interrupts are an exception */ /* Release bandwidth for Interrupt or Isoc. transfers */ /* Spinlock needed ? */ /* We decrement the usage count after we're done with everything */